Introduction

The growth factor receptor network (GFRN) contributes to breast cancer progression and drug response. This RNA-Seq dataset (Rahman et al. 2017) is designed to develop gene signatures for several GFRN pathways: AKT, BAD, HER2, IGF1R, RAF1, KRAS, and EGFR. The study used recombinant adenoviruses to express these genes in case samples and produce green fluorescent protein (GFP) in control samples, using replicates of human mammary epithelial cells (HMECs). RNA-Seq data are collected from these HMECs overexpressing GFRN genes and GFP controls.

Overall design

The dataset contains 3 batches, with a total of 89 samples:

  • Batch 1 (GSE83083): 41 samples. 6 replicate samples of each for AKT, BAD, IGF1R, and RAF1, 5 replicates for HER2, and 12 replicates for GFP controls
  • Batch 2 (GSE59765): 12 samples. 6 replicates of each for EGFR and its corresponding controls
  • Batch 3 (GSE83083): 36 samples. 9 replicates of each for 3 types of KRAS mutants and GFP control

Load data & basic info

A few basic statistics of the dataset:

######  Samples  #######
- Total number of samples:
[1] 89

- Number of samples in condition groups:
group_num
 0  1  2  3  4  5  6  7  8  9 
27  6  6  6  5  6  9  9  9  6 
In batch 1:
  akt   bad gfp18  her2 igf1r   raf 
    6     6    12     5     6     6 
In batch 2:
        egfr gfp_for_egfr 
           6            6 
In batch 3:
 gfp30 krasgv krasqh kraswt 
     9      9      9      9 

- Number of samples in batches:
batch
 1  2  3 
41 12 36 


######  Genes  #######
- Total number of genes:
[1] 23368

- Number of genes with 0 counts:
10097 43.2%

- Number of genes with maximum 10 counts:
7868 33.7%

- Number of genes with ONLY 0s:
2500 10.7%


######  Counts  #######
- Range of count in whole dataset:
[1]       0 2270900

- Average count in whole dataset:
[1] "Mean: 886.527"
[1] "Median: 45"

For the following analysis, we remove genes with only zero values across all samples.

## Remove genes with all 0 counts
sigdata <- sigdata[apply(cts_mat, 1, function(x){!all(x==0)}), ]
cts_mat <- assay(sigdata, "counts")
rownames(cts_mat) <- paste0("gene", 1:nrow(sigdata))
print(dim(cts_mat))
[1] 20868    89

The figure below shows distribution of percentages of zero counts for the remaining genes (each data point represents a gene, i.e., how many 0 counts are there in each gene).

######  Proportion of genes with X% zeros across samples  #######
 <10.0%  <20.0%  <30.0%  <40.0%  <50.0%  <60.0%  <70.0%  <80.0%  <90.0% <100.0% 
  0.703   0.045   0.020   0.016   0.017   0.017   0.020   0.025   0.039   0.097 

Existence of batch effect

We first visualize the data using PCA and hierarchical clustering, to see the batch effect in the dataset. Especially, Batch 2 separates from the other two batches in PCA plots.

PCA

Dendrograms

Library size

Next, we take a look at the observed library sizes of samples, and to see if there is a difference in library size across batches.

Range of observed library sizes across samples:
[1] "1.0e+07" "3.4e+07"

Gene expression distribution

Our next step is to interrogate the gene expression distributions.

We first simply plot the counts, CPM, and log2CPM of 20 randomly chosen genes in the dataset. These figures are stored under directory specified by output_dir.

Fold changes in mean

We then use edgeR to perform differential expression analysis, and calculate (log-) fold changes of all genes between condition groups and batches.

Change WRT condition

To rule out the impact of batch effect, we limit our DE analysis with regard to biological condition in one of the batches. Here we specify the batch to be Batch 2: EGFR vs GFP control.

####  Differential genes relative to biological condition 
####  (within batch specified by 'test_batch')
test_batch <- 2
counts_batch <- cts_mat[, batch==test_batch]
cond_batch <- group_num[batch==test_batch]
y <- DGEList(counts=counts_batch, group=as.factor(cond_batch))
y <- calcNormFactors(y, method="TMM")
design <- model.matrix(~as.factor(cond_batch))
y <- estimateDisp(y, design)
fit <- glmQLFit(y, design)
qlf <- glmQLFTest(fit, coef=2)
de_res <- topTags(qlf, n=nrow(sigdata))
 
up_genes <- rownames(de_res)[which(de_res$table$logFC >= 0)]  # all up-regulated genes (descending order in terms of p value)
head_up_genes <- head(up_genes, n=50)  # top-50 significant up-regulated genes
tail_up_genes <- tail(up_genes, n=50)  # 50 least significant up-regulated genes
cond_up_inds <- up_genes 
down_genes <- rownames(de_res)[which(de_res$table$logFC < 0)]  # all down-regulated genes
head_down_genes <- head(down_genes, n=50)  # top-50 significant down-regulated genes
tail_down_genes <- tail(down_genes, n=50)  # 50 least significant down-regulated genes
cond_down_inds <- down_genes
######  Changes in terms of average gene counts  ######
     top50 up top50 down 100 least DE
GFP    1535.8     4700.0        325.2
EGFR   2142.5     3570.9        321.2

######  Range of fold change across biological conditions  ######
          top50 up top50 down 100 least DE
min FC       1.421      0.296        0.988
median FC    1.652      0.648        1.000
mean FC      1.809      0.616        0.999
max FC       3.657      0.766        1.000

######  Range of Log(fold change) across biological conditions  ######
             top50 up top50 down 100 least DE
min logFC       0.352     -1.219       -0.012
median logFC    0.502     -0.434        0.000
mean logFC      0.593     -0.484       -0.001
max logFC       1.297     -0.266        0.000

Conclusions:

  • Biological fold change comparing average counts in top DE genes is about 1.3-1.4.
  • Gene-wise fold change ranges in top DE genes from 1.7-1.8.

Change WRT batch

We are also interested to see how the average (mean) gene counts change across batches (i.e. degree of mean batch effect).

To explore this mean batch effect, we first perform DE with regard to the batch variable. To rule out the impact of biological condition, we perform this analysis within control samples only. Since from the PCA plot, Batch 2 separates from the other two batches more, we compare Batch 1 and 2 in this case.

####  Differential genes relative to batch 
####  (within condition 0 / condition specified by 'test_cond')
test_cond <- 0
counts_cond <- cts_mat[, (group_num==test_cond) & (batch!=3)]
batch_cond <- batch[(group_num==test_cond) & (batch!=3)]
y <- DGEList(counts=counts_cond, group=as.factor(batch_cond))
y <- calcNormFactors(y, method="TMM")
design <- model.matrix(~as.factor(batch_cond))
y <- estimateDisp(y, design)
fit <- glmQLFit(y, design)
qlf <- glmQLFTest(fit, coef=2)
de_res <- topTags(qlf, n=nrow(sigdata))
up_genes <- rownames(de_res)[which(de_res$table$logFC >= 0)]  # all up-regulated genes
head_up_genes <- head(up_genes, n=50)  # top-50 up-regulated genes
tail_up_genes <- tail(up_genes, n=50)  # 50 least up-regulated genes
batch_up_inds <- up_genes
down_genes <- rownames(de_res)[which(de_res$table$logFC < 0)]  # all down-regulated genes
head_down_genes <- head(down_genes, n=50)  # top-50 down-regulated genes
tail_down_genes <- tail(down_genes, n=50)  # 50 least down-regulated genes
batch_down_inds <- down_genes
######  Batch differences in terms of mean gene counts  ######
       top50 up top50 down 100 least changed
Batch1    389.6     4653.5              42.6
Batch2   4001.1      158.2              57.3

######  Range of fold change between batches  ######
- All genes - FC:
0 34381.28

- All genes - log(FC):
-15.972 10.445

- Top genes - FC:
           top50 up top50 down 100 least DE
min FC        7.664      0.000        0.979
median FC    27.103      0.001        1.000
mean FC     404.109      0.008        0.996
max FC    12757.952      0.059        1.000

- Top genes - log(FC):
             top50 up top50 down 100 least DE
min logFC       2.037    -15.972       -0.021
median logFC    3.300     -6.866        0.000
mean logFC      6.002     -4.881       -0.004
max logFC       9.454     -2.836        0.000

Conclusion:

  • Mean batch effect fold change comparing average counts in top genes is quite large. But remember, these are top genes that change across batches.

Batch mean

Median (of all genes) gene-wise mean:

         Batch1 Batch2 Batch3
Controls  90.17  98.33 114.94
Cases     80.33  95.67 151.22

Scaled by that of batch 1:

         Batch1 Batch2 Batch3
Controls      1   1.09   1.27
Cases         1   1.19   1.88

Batch dispersion

Aside from average gene counts, we are interested in comparing dispersions in the batches. Difference in the dispersions across batches suggests variance batch effect that are not accounted for by Poisson model. We visualize the gene-wise dispersion estimates from edgeR:

####  Statistics about dispersion estimates from the batches  ####
             Batch1 Batch2 Batch3
min disp.    0.0001 0.0001 0.0001
median disp. 0.0075 0.0059 0.0027
mean disp.   0.0235 0.0309 0.0147
max disp.    1.0377 2.8392 1.6146

Conclusions:

  • Max mean dispersion difference: Batch 2 is about 2 times of those in Batch 3.

Batch variance

Median (of all genes) gene-wise variance:

         Batch1 Batch2 Batch3
Controls 488.66 475.07 518.43
Cases    179.53 870.22 671.43

Scaled by that of batch 1:

         Batch1 Batch2 Batch3
Controls      1   0.97   1.06
Cases         1   4.85   3.74

Impact of 0 counts on gene distributions

We have seen that a lot of genes in the dataset contain some portion of zeros. Having 0 counts can have a great impact on mean and dispersion estimation. We evaluate such impact in this section, and see how NB distribution fits to non-zero portion of genes. We first take the non-zero portion of the genes.

Fold change in mean in non-zero portion

Change WRT condition in batch 2

Within batch 2, we compare mean (here refers to non-zero mean) across biological condition groups. Specifically, we saved the previous DE analysis results using edgeR, on counts containing zeros. We call all genes with \(\log(FC) >= 0\) as “up” genes, and \(\log(FC) < 0\) as “down” genes. The top 50 “up” and “down” genes (with smallest p values) are still determined by the previous DE containing zeros.

######  Changes in MEAN non-zero gene counts  ######
     top50 up top50 down 100 least DE
GFP    1535.8     4700.0        668.3
EGFR   2142.5     3570.9        673.9
######  Changes in MEDIAN non-zero gene counts  ######
     top50 up top50 down 100 least DE
GFP    1078.5     1691.5        178.5
EGFR   1499.0     1188.5        175.5

Conclusions:

  • Biological fold change (in non-zero portion) comparing average counts in top genes is about 1.3-1.4 (mean), 1.39 - 1.42 (median).**
  • O counts did not strongly affect biological signal in terms of average counts in top genes.

Change WRT batch in control samples

Similarly, we compare non-zero mean in top genes across batches within control samples. Here “top genes” refer to top gene lists from previous DE within control samples comparing batches.

######  Changes in MEAN non-zero gene counts  ######
        top50 up top50 down 100 least DE
Batch 1    394.8     4653.5        184.7
Batch 2   4001.1      189.9        213.5
######  Changes in MEDIAN non-zero gene counts  ######
        top50 up top50 down 100 least DE
Batch 1    176.5       2048            2
Batch 2   2720.5         41            2

Conclusions:

  • Mean batch effect fold change comparing average counts in top genes is very large.
  • O counts did not strongly affect mean batch effect in terms of average counts in top genes.

Batch mean with 0 counts removed

Median (of all genes) gene-wise mean after removing zeros:

         Batch1 Batch2 Batch3
Controls 138.96 217.17 184.39
Cases    158.58 214.17 223.83

Scaled by that of batch 1:

         Batch1 Batch2 Batch3
Controls      1   1.56   1.33
Cases         1   1.35   1.41

Batch dispersion with 0 counts removed

Dispersion estimates are more likely impacted by 0 counts. We re-estimate the dispersions in each batch, using non-zero portion of each gene. Then we compare the dispersion estimates across batches.

####  Statistics about dispersion estimates (from NON-ZERO portions) from the two batches  ####
             Batch1 Batch2 Batch3
min disp.    0.0000 0.0000 0.0000
median disp. 0.0268 0.0512 0.0148
mean disp.   0.0271 0.0522 0.0163
max disp.    0.8216 2.2998 0.6972

Conclusions:

  • The absolute value of maximum dispersion are reduced after 0 counts are removed.
  • In this report, dispersion are calculated by different methods before and after removing 0 counts. Not directly comparable.
  • We show in another analysis (gfrnSig_run_nonzero_disps.R) that the relationship between batches did not change much after removing 0s.

Batch variance with 0 counts removed

Median gene-wise variance after removing zeros:

          Batch1  Batch2  Batch3
Controls 1475.48 3331.57 1758.75
Cases     657.83 7140.48 2179.06

Scaled by that of batch 1:

         Batch1 Batch2 Batch3
Controls      1   2.26   1.19
Cases         1  10.85   3.31

Is there a difference in zero portions across batches?

Another question related to batch effect, is whether there is any difference in the percentage of 0 counts in a gene between batches.

Conclusions:

  • There is a certain level of difference in zero fractions between batches. Specifically, Batch 3 has more relatively “complete” (fewer 0 counts) genes than Batches 1 & 2.

Goodness of fit for NB distribution to non-zero portion of genes

It is difficult to evaluate quantitatively the goodness-of-fit of NB distribution on data. Instead, we generate Q-Q plots for 100 randomly selected genes, comparing data with NB distribution using ML estimated parameters. We generate these plots within batch 2, for cases and control samples separately. Figures are stored under {output_dir}/qqplots/.

More justification for having different dispersion parameter for different batches

Finally, a very important assumption of ComBat-seq model (compared to adding batch covariates in linear model of edgeR and DESeq), is that having a different dispersion parameter for each batch is beneficial for DE performance. As argued by many, if not all, of these papers, accurate estimation of dispersion paramters are important for DE detection. As we have seen above, there is some difference in dispersion distribution across batches. If dispersion estimates within each batch and using the whole study are not consistent with each other, then it is justification that we may need different dipsersion parameter for different batches, and it could be good for DE.

Here we generate scatter plots comparing dispersion estimates within each batch to estimates from whole dataset (including batch as a covariate in whole study).

Gene-wise dispersion estimates

Trended dispersion estimates (log10 scale)

Session info

R version 3.5.1 (2018-07-02)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS High Sierra 10.13.6

Matrix products: default
BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/3.5/Resources/lib/libRlapack.dylib

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] parallel  stats4    stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] MASS_7.3-51                 ggdendro_0.1-20             scales_1.0.0                gridExtra_2.3              
 [5] reshape2_1.4.3              ggplot2_3.0.0               dendextend_1.9.0            DESeq2_1.20.0              
 [9] SummarizedExperiment_1.10.1 DelayedArray_0.6.6          BiocParallel_1.14.2         matrixStats_0.54.0         
[13] Biobase_2.40.0              GenomicRanges_1.32.7        GenomeInfoDb_1.16.0         IRanges_2.14.12            
[17] S4Vectors_0.18.3            BiocGenerics_0.26.0         edgeR_3.22.5                limma_3.36.5               

loaded via a namespace (and not attached):
 [1] bitops_1.0-6           bit64_0.9-7            RColorBrewer_1.1-2     prabclus_2.2-6         tools_3.5.1           
 [6] backports_1.1.2        R6_2.3.0               rpart_4.1-13           Hmisc_4.1-1            DBI_1.0.0             
[11] lazyeval_0.2.1         colorspace_1.3-2       trimcluster_0.1-2.1    nnet_7.3-12            withr_2.1.2           
[16] tidyselect_0.2.5       bit_1.1-14             compiler_3.5.1         htmlTable_1.12         labeling_0.3          
[21] diptest_0.75-7         checkmate_1.8.5        DEoptimR_1.0-8         mvtnorm_1.0-8          robustbase_0.93-3     
[26] genefilter_1.62.0      stringr_1.3.1          digest_0.6.18          foreign_0.8-71         XVector_0.20.0        
[31] base64enc_0.1-3        pkgconfig_2.0.2        htmltools_0.3.6        htmlwidgets_1.3        rlang_0.3.0           
[36] rstudioapi_0.8         RSQLite_2.1.1          bindr_0.1.1            mclust_5.4.1           acepack_1.4.1         
[41] dplyr_0.7.7            RCurl_1.95-4.11        magrittr_1.5           modeltools_0.2-22      GenomeInfoDbData_1.1.0
[46] Formula_1.2-3          Matrix_1.2-14          Rcpp_0.12.19           munsell_0.5.0          viridis_0.5.1         
[51] stringi_1.2.4          whisker_0.3-2          yaml_2.2.0             zlibbioc_1.26.0        flexmix_2.3-14        
[56] plyr_1.8.4             grid_3.5.1             blob_1.1.1             crayon_1.3.4           lattice_0.20-35       
[61] splines_3.5.1          annotate_1.58.0        locfit_1.5-9.1         knitr_1.20             pillar_1.3.0          
[66] fpc_2.1-11.1           geneplotter_1.58.0     XML_3.98-1.16          glue_1.3.0             latticeExtra_0.6-28   
[71] data.table_1.11.8      gtable_0.2.0           purrr_0.2.5            kernlab_0.9-27         assertthat_0.2.0      
[76] xtable_1.8-3           viridisLite_0.3.0      class_7.3-14           survival_2.42-6        tibble_1.4.2          
[81] AnnotationDbi_1.42.1   memoise_1.1.0          bindrcpp_0.2.2         cluster_2.0.7-1       

References

Rahman, Mumtahena, Shelley M MacNeil, David F Jenkins, Gajendra Shrestha, Sydney R Wyatt, Jasmine A McQuerry, Stephen R Piccolo, et al. 2017. “Activity of Distinct Growth Factor Receptor Network Components in Breast Tumors Uncovers Two Biologically Relevant Subtypes.” Genome Medicine 9 (1). BioMed Central: 40.

LS0tCnRpdGxlOiAiRXhwbG9yYXRpb24gb2YgcmVhbCBidWxrIFJOQS1zZXEgZGF0YXNldHMiCnN1YnRpdGxlOiAiR0ZSTiBzaWduYXR1cmUgZGF0YXNldCIKYXV0aG9yOiBZdXFpbmcgWmhhbmcKZGF0ZTogImByIFN5cy5EYXRlKClgIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIHRoZW1lOiB1bml0ZWQKICAgIHRvYzogeWVzCmJpYmxpb2dyYXBoeTogcmVmcy5iaWIKLS0tCgojIyBJbnRyb2R1Y3Rpb24KClRoZSBncm93dGggZmFjdG9yIHJlY2VwdG9yIG5ldHdvcmsgKEdGUk4pIGNvbnRyaWJ1dGVzIHRvIGJyZWFzdCBjYW5jZXIgcHJvZ3Jlc3Npb24gYW5kIGRydWcgcmVzcG9uc2UuIFRoaXMgUk5BLVNlcSBkYXRhc2V0IFtAcmFobWFuMjAxN2FjdGl2aXR5XSBpcyBkZXNpZ25lZCB0byBkZXZlbG9wIGdlbmUgc2lnbmF0dXJlcyBmb3Igc2V2ZXJhbCBHRlJOIHBhdGh3YXlzOiBBS1QsIEJBRCwgSEVSMiwgSUdGMVIsIFJBRjEsIEtSQVMsIGFuZCBFR0ZSLiBUaGUgc3R1ZHkgdXNlZCByZWNvbWJpbmFudCBhZGVub3ZpcnVzZXMgdG8gZXhwcmVzcyB0aGVzZSBnZW5lcyBpbiBjYXNlIHNhbXBsZXMgYW5kIHByb2R1Y2UgZ3JlZW4gZmx1b3Jlc2NlbnQgcHJvdGVpbiAoR0ZQKSBpbiBjb250cm9sIHNhbXBsZXMsIHVzaW5nIHJlcGxpY2F0ZXMgb2YgaHVtYW4gbWFtbWFyeSBlcGl0aGVsaWFsIGNlbGxzIChITUVDcykuIFJOQS1TZXEgZGF0YSBhcmUgY29sbGVjdGVkIGZyb20gdGhlc2UgSE1FQ3Mgb3ZlcmV4cHJlc3NpbmcgR0ZSTiBnZW5lcyBhbmQgR0ZQIGNvbnRyb2xzLiAKCiMjIyBPdmVyYWxsIGRlc2lnbgoKVGhlIGRhdGFzZXQgY29udGFpbnMgMyBiYXRjaGVzLCB3aXRoIGEgdG90YWwgb2YgODkgc2FtcGxlczoKCisgQmF0Y2ggMSAoW0dTRTgzMDgzXShodHRwczovL3d3dy5uY2JpLm5sbS5uaWguZ292L2dlby9xdWVyeS9hY2MuY2dpP2FjYz1HU0U4MzA4MykpOiA0MSBzYW1wbGVzLiA2IHJlcGxpY2F0ZSBzYW1wbGVzIG9mIGVhY2ggZm9yIEFLVCwgQkFELCBJR0YxUiwgYW5kIFJBRjEsIDUgcmVwbGljYXRlcyBmb3IgSEVSMiwgYW5kIDEyIHJlcGxpY2F0ZXMgZm9yIEdGUCBjb250cm9scworIEJhdGNoIDIgKFtHU0U1OTc2NV0oaHR0cHM6Ly93d3cubmNiaS5ubG0ubmloLmdvdi9nZW8vcXVlcnkvYWNjLmNnaT9hY2M9R1NFNTk3NjUpKTogMTIgc2FtcGxlcy4gNiByZXBsaWNhdGVzIG9mIGVhY2ggZm9yIEVHRlIgYW5kIGl0cyBjb3JyZXNwb25kaW5nIGNvbnRyb2xzICAKKyBCYXRjaCAzIChbR1NFODMwODNdKGh0dHBzOi8vd3d3Lm5jYmkubmxtLm5paC5nb3YvZ2VvL3F1ZXJ5L2FjYy5jZ2k/YWNjPUdTRTgzMDgzKSk6IDM2IHNhbXBsZXMuIDkgcmVwbGljYXRlcyBvZiBlYWNoIGZvciAzIHR5cGVzIG9mIEtSQVMgbXV0YW50cyBhbmQgR0ZQIGNvbnRyb2wKCiMjIyBMb2FkIGRhdGEgJiBiYXNpYyBpbmZvCgpgYGB7ciwgZWNobz1GQUxTRSwgcmVzdWx0cz0naGlkZSd9CnJtKGxpc3Q9bHMoKSkKb3V0cHV0X2RpciA8LSAifi9Hb29nbGUgRHJpdmUvQ29tQmF0X3NlcS9yZWFsX2RhdGFfZXhhbXBsZS9STkFzZXEvZ2Zybl9zaWduYXR1cmUiCnNhcHBseShjKCJTdW1tYXJpemVkRXhwZXJpbWVudCIsICJERVNlcTIiLCAiZWRnZVIiLCAiZGVuZGV4dGVuZCIsICJnZ3Bsb3QyIiwgInJlc2hhcGUyIiwgImdyaWRFeHRyYSIsIAogICAgICAgICAic2NhbGVzIiwgImdnZGVuZHJvIiwgIk1BU1MiKSwgcmVxdWlyZSwgY2hhcmFjdGVyLm9ubHk9VFJVRSkKCiMjIyMgIExvYWQgZGF0YQojZGF0YV9kaXIgPC0gIi9yZXN0cmljdGVkL3Byb2plY3RuYi9wYXRoc2lnL3NpZ25hdHVyZXMvZmFzdHEvdTAxX2NvbWJpbmVkIgpzaWdkYXRhIDwtIHJlYWRSRFMoZmlsZS5wYXRoKG91dHB1dF9kaXIsICJzaWduYXR1cmVfZGF0YS5yZHMiKSkKI2NvdW50IG1hdHJpeCAoYWxzbyBoYXZlIHRwbSBhbmQgZnBrbSBpbiB0aGVyZSkKY3RzX21hdCA8LSBhc3NheShzaWdkYXRhLCAiY291bnRzIikKcm93bmFtZXMoY3RzX21hdCkgPC0gcGFzdGUwKCJnZW5lIiwgMTpucm93KGN0c19tYXQpKQojYmF0Y2ggYW5ub3RhdGlvbgpiYXRjaCA8LSBjb2xEYXRhKHNpZ2RhdGEpJGJhdGNoCiNzaWduYXR1cmUgYW5ub3RhdGlvbgpncm91cCA8LSBjb2xEYXRhKHNpZ2RhdGEpJGdyb3VwCgpncm91cF9udW0gPC0gcmVwKDAsIG5jb2woY3RzX21hdCkpCmNvbmRfbmFtZXMgPC0gbGV2ZWxzKGdyb3VwKVtjKDE6Myw3Om5sZXZlbHMoZ3JvdXApKV0KZm9yKGkgaW4gMTpsZW5ndGgoY29uZF9uYW1lcykpe2dyb3VwX251bVtncmVwKHBhc3RlMCgiXiIsY29uZF9uYW1lc1tpXSksIGdyb3VwKV0gPC0gaX0KY29sRGF0YShzaWdkYXRhKSRjb25kaXRpb25fYmkgPC0gYXMuZmFjdG9yKGdyb3VwX251bSkKY29sRGF0YShzaWdkYXRhKSRiYXRjaCA8LSBhcy5mYWN0b3IoYmF0Y2gpCmBgYAoKQSBmZXcgYmFzaWMgc3RhdGlzdGljcyBvZiB0aGUgZGF0YXNldDoKCmBgYHtyLCBlY2hvPUZBTFNFfQpjYXQoIiMjIyMjIyAgU2FtcGxlcyAgIyMjIyMjI1xuIikKY2F0KCItIFRvdGFsIG51bWJlciBvZiBzYW1wbGVzOlxuIikKcHJpbnQobmNvbChjdHNfbWF0KSkKCmNhdCgiXG4tIE51bWJlciBvZiBzYW1wbGVzIGluIGNvbmRpdGlvbiBncm91cHM6XG4iKQpwcmludCh0YWJsZShncm91cF9udW0pKQpjYXQoIkluIGJhdGNoIDE6IikKcHJpbnQodGFibGUoYXMuY2hhcmFjdGVyKGdyb3VwKVtiYXRjaD09MV0pKQpjYXQoIkluIGJhdGNoIDI6IikKcHJpbnQodGFibGUoYXMuY2hhcmFjdGVyKGdyb3VwKVtiYXRjaD09Ml0pKQpjYXQoIkluIGJhdGNoIDM6IikKcHJpbnQodGFibGUoYXMuY2hhcmFjdGVyKGdyb3VwKVtiYXRjaD09M10pKQoKY2F0KCJcbi0gTnVtYmVyIG9mIHNhbXBsZXMgaW4gYmF0Y2hlczpcbiIpCnByaW50KHRhYmxlKGJhdGNoKSkKCgpjYXQoIlxuXG4jIyMjIyMgIEdlbmVzICAjIyMjIyMjXG4iKQpjYXQoIi0gVG90YWwgbnVtYmVyIG9mIGdlbmVzOlxuIikKcHJpbnQobnJvdyhjdHNfbWF0KSkKCmNhdCgiXG4tIE51bWJlciBvZiBnZW5lcyB3aXRoIDAgY291bnRzOlxuIikKZ2VuZV9yb3dfd2l0aF96ZXJvcyA8LSBhcHBseShjdHNfbWF0LCAxLCBmdW5jdGlvbih4KXthbnkoeD09MCl9KQpjYXQoYyhzdW0oZ2VuZV9yb3dfd2l0aF96ZXJvcyksIHBlcmNlbnQoc3VtKGdlbmVfcm93X3dpdGhfemVyb3MpL25yb3coY3RzX21hdCkpKSkKCmNhdCgiXG5cbi0gTnVtYmVyIG9mIGdlbmVzIHdpdGggbWF4aW11bSAxMCBjb3VudHM6XG4iKQpnZW5lX3Jvd19sb3cgPC0gYXBwbHkoY3RzX21hdCwgMSwgZnVuY3Rpb24oeCl7YWxsKHg8PTEwKX0pCmNhdChjKHN1bShnZW5lX3Jvd19sb3cpLCBwZXJjZW50KHN1bShnZW5lX3Jvd19sb3cpL25yb3coY3RzX21hdCkpKSkKCmNhdCgiXG5cbi0gTnVtYmVyIG9mIGdlbmVzIHdpdGggT05MWSAwczpcbiIpCmdlbmVfYWxsX3plcm9zIDwtIGFwcGx5KGN0c19tYXQsIDEsIGZ1bmN0aW9uKHgpe2FsbCh4PT0wKX0pCmNhdChjKHN1bShnZW5lX2FsbF96ZXJvcyksIHBlcmNlbnQoc3VtKGdlbmVfYWxsX3plcm9zKS9ucm93KGN0c19tYXQpKSkpCgoKY2F0KCJcblxuXG4jIyMjIyMgIENvdW50cyAgIyMjIyMjI1xuIikKY2F0KCItIFJhbmdlIG9mIGNvdW50IGluIHdob2xlIGRhdGFzZXQ6XG4iKQpwcmludChyb3VuZChyYW5nZShjdHNfbWF0KSwgMykpCgpjYXQoIlxuLSBBdmVyYWdlIGNvdW50IGluIHdob2xlIGRhdGFzZXQ6XG4iKQpwcmludChwYXN0ZSgiTWVhbjoiLCByb3VuZChtZWFuKGN0c19tYXQpLCAzKSkpCnByaW50KHBhc3RlKCJNZWRpYW46Iiwgcm91bmQobWVkaWFuKGN0c19tYXQpLCAzKSkpCgpybShnZW5lX3Jvd193aXRoX3plcm9zLCBnZW5lX3Jvd19sb3csIGdlbmVfYWxsX3plcm9zKQpgYGAKCkZvciB0aGUgZm9sbG93aW5nIGFuYWx5c2lzLCAqKndlIHJlbW92ZSBnZW5lcyB3aXRoIG9ubHkgemVybyB2YWx1ZXMgYWNyb3NzIGFsbCBzYW1wbGVzKiouIAoKYGBge3J9CiMjIFJlbW92ZSBnZW5lcyB3aXRoIGFsbCAwIGNvdW50cwpzaWdkYXRhIDwtIHNpZ2RhdGFbYXBwbHkoY3RzX21hdCwgMSwgZnVuY3Rpb24oeCl7IWFsbCh4PT0wKX0pLCBdCmN0c19tYXQgPC0gYXNzYXkoc2lnZGF0YSwgImNvdW50cyIpCnJvd25hbWVzKGN0c19tYXQpIDwtIHBhc3RlMCgiZ2VuZSIsIDE6bnJvdyhzaWdkYXRhKSkKcHJpbnQoZGltKGN0c19tYXQpKQpgYGAKClRoZSBmaWd1cmUgYmVsb3cgc2hvd3MgZGlzdHJpYnV0aW9uIG9mIHBlcmNlbnRhZ2VzIG9mIHplcm8gY291bnRzIGZvciB0aGUgcmVtYWluaW5nIGdlbmVzIChlYWNoIGRhdGEgcG9pbnQgcmVwcmVzZW50cyBhIGdlbmUsIGkuZS4sIGhvdyBtYW55IDAgY291bnRzIGFyZSB0aGVyZSBpbiBlYWNoIGdlbmUpLgoKYGBge3IsIGVjaG89RkFMU0V9Cm5femVyb3NfaW5fZ2VuZXMgPC0gYXBwbHkoY3RzX21hdCwgMSwgZnVuY3Rpb24oeCl7bGVuZ3RoKHdoaWNoKHg9PTApKX0pCnBlcmNlbnRfemVyb3NfaW5fZ2VuZXMgPC0gbl96ZXJvc19pbl9nZW5lcyAvIG5jb2woc2lnZGF0YSkKcGVyY2VudF96ZXJvc19kZiA8LSBkYXRhLmZyYW1lKGdlbmVzPTE6bnJvdyhzaWdkYXRhKSwgdmFsdWU9cGVyY2VudF96ZXJvc19pbl9nZW5lcykKCmJpbm5lZF9jdHMgPC0gaGlzdChwZXJjZW50X3plcm9zX2luX2dlbmVzLCBicmVha3M9MTAsIHBsb3Q9RkFMU0UpJGNvdW50cyAKYmlubmVkX3Byb3BvcnRpb25zIDwtIGJpbm5lZF9jdHMgLyBzdW0oYmlubmVkX2N0cykKbmFtZXMoYmlubmVkX3Byb3BvcnRpb25zKSA8LSBwYXN0ZTAoIjwiLCBwZXJjZW50KHNlcShmcm9tPTAuMSwgdG89MSwgYnk9MC4xKSkpICAKY2F0KCIjIyMjIyMgIFByb3BvcnRpb24gb2YgZ2VuZXMgd2l0aCBYJSB6ZXJvcyBhY3Jvc3Mgc2FtcGxlcyAgIyMjIyMjI1xuIikKcHJpbnQocm91bmQoYmlubmVkX3Byb3BvcnRpb25zLDMpKQoKZ2dwbG90KHBlcmNlbnRfemVyb3NfZGYsIGFlcygwLCB2YWx1ZSkpICsgCiAgICAgIGdlb21fdmlvbGluKCkgKwogICAgICBnZW9tX2JveHBsb3QoYWVzKDAuNywgdmFsdWUpLCB3aWR0aD0wLjE1KSArCiAgICAgIGNvb3JkX2ZsaXAoKSArCiAgICAgIGFubm90YXRlKGdlb209InRleHQiLCBsYWJlbD1wZXJjZW50KG1lZGlhbihwZXJjZW50X3plcm9zX2RmJHZhbHVlKSksIHg9MC44NSwgeT1tZWRpYW4ocGVyY2VudF96ZXJvc19kZiR2YWx1ZSkpICsKICAgICAgbGFicyh5PSIlIFplcm9zIiwgdGl0bGU9IlByb3BvcnRpb24gb2YgemVyb3MgYWNyb3NzIHNhbXBsZXMgZm9yIHRoZSByZW1haW5pbmcgZ2VuZXMiKSArCiAgICAgIHRoZW1lKGF4aXMudGl0bGUueT1lbGVtZW50X2JsYW5rKCkpIywgYXhpcy50ZXh0Lnk9ZWxlbWVudF9ibGFuaygpKQpgYGAKCmBgYHtyLCBlY2hvPUZBTFNFfQpybShuX3plcm9zX2luX2dlbmVzLCBwZXJjZW50X3plcm9zX2luX2dlbmVzLCBwZXJjZW50X3plcm9zX2RmKQpgYGAKCgoKIyMgRXhpc3RlbmNlIG9mIGJhdGNoIGVmZmVjdCB7LnRhYnNldH0KCldlIGZpcnN0IHZpc3VhbGl6ZSB0aGUgZGF0YSB1c2luZyBQQ0EgYW5kIGhpZXJhcmNoaWNhbCBjbHVzdGVyaW5nLCB0byBzZWUgdGhlIGJhdGNoIGVmZmVjdCBpbiB0aGUgZGF0YXNldC4gRXNwZWNpYWxseSwgQmF0Y2ggMiBzZXBhcmF0ZXMgZnJvbSB0aGUgb3RoZXIgdHdvIGJhdGNoZXMgaW4gUENBIHBsb3RzLiAKCiMjIyBQQ0EKCmBgYHtyLCBlY2hvPUZBTFNFLCBmaWcuaGVpZ2h0PTIsIGZpZy53aWR0aD01fQpwY2Ffb2JqIDwtIHBsb3RQQ0EoREVTZXFUcmFuc2Zvcm0oc2lnZGF0YSksIGludGdyb3VwPWMoImJhdGNoIiwgImNvbmRpdGlvbl9iaSIpKSAKY29sbmFtZXMocGNhX29iaiRkYXRhKVs1XSA8LSAiY29uZCIKcF9iYXRjaCA8LSBnZ3Bsb3QocGNhX29iaiRkYXRhLCBhZXMoeD1QQzEsIHk9UEMyLCBjb2xvcj1iYXRjaCkpICsKICBnZW9tX3BvaW50KCkgKyAKICBsYWJzKHg9c3ByaW50ZigiUEMxOiAlcyBWYXJpYW5jZSIsIHBlcmNlbnQocGNhX29iaiRwbG90X2VudiRwZXJjZW50VmFyWzFdKSksCiAgICAgICB5PXNwcmludGYoIlBDMjogJXMgVmFyaWFuY2UiLCBwZXJjZW50KHBjYV9vYmokcGxvdF9lbnYkcGVyY2VudFZhclsyXSkpLAogICAgICAgdGl0bGU9IlBDQTogc2FtcGxlcyBjb2xvcmVkIGJ5IEJhdGNoIikKcF9jb25kIDwtIGdncGxvdChwY2Ffb2JqJGRhdGEsIGFlcyh4PVBDMSwgeT1QQzIsIGNvbG9yPWNvbmQpKSArCiAgZ2VvbV9wb2ludCgpICsgCiAgbGFicyh4PXNwcmludGYoIlBDMTogJXMgVmFyaWFuY2UiLCBwZXJjZW50KHBjYV9vYmokcGxvdF9lbnYkcGVyY2VudFZhclsxXSkpLAogICAgICAgeT1zcHJpbnRmKCJQQzI6ICVzIFZhcmlhbmNlIiwgcGVyY2VudChwY2Ffb2JqJHBsb3RfZW52JHBlcmNlbnRWYXJbMl0pKSwKICAgICAgIHRpdGxlPSJQQ0E6IHNhbXBsZXMgY29sb3JlZCBieSBDb25kaXRpb24iKQpncmlkLmFycmFuZ2UocF9iYXRjaCwgcF9jb25kLCBuY29sPTIpCmBgYAoKIyMjIERlbmRyb2dyYW1zCgpgYGB7ciwgZWNobz1GQUxTRSwgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9NX0KY291bnRzX25vcm0gPC0gc2NhbGUodChjdHNfbWF0KSwgY2VudGVyPVRSVUUsIHNjYWxlPVRSVUUpCmhjIDwtIGhjbHVzdChkaXN0KGNvdW50c19ub3JtKSkKZGVuZCA8LSBhcy5kZW5kcm9ncmFtKGhjKQpkZGF0YSA8LSBkZW5kcm9fZGF0YShkZW5kLCB0eXBlID0gInJlY3RhbmdsZSIpCgptZXRhX2luZm8gPC0gZGF0YS5mcmFtZShjb2xEYXRhKHNpZ2RhdGEpWywgYygiYmF0Y2giLCAiY29uZGl0aW9uX2JpIildLCBzYW1wbGU9Y29sbmFtZXMoc2lnZGF0YSkpCmNvbG5hbWVzKG1ldGFfaW5mbylbMl0gPC0gImNvbmQiCnRtcCA8LSBtZXJnZSh4PWRkYXRhJGxhYmVscywgeT1tZXRhX2luZm8sIGJ5Lng9ImxhYmVsIiwgYnkueT0ic2FtcGxlIikKCnBkX2JhdGNoIDwtIGdncGxvdChzZWdtZW50KGRkYXRhKSkgKyAKICBnZW9tX3NlZ21lbnQoYWVzKHg9eCwgeT15LCB4ZW5kPXhlbmQsIHllbmQ9eWVuZCkpICsgCiAgY29vcmRfZmxpcCgpICsgc2NhbGVfeV9yZXZlcnNlKCkgKwogIGdlb21fdGV4dChkYXRhPXRtcCwgYWVzKGxhYmVsPWFzLmNoYXJhY3Rlcih0bXAkbGFiZWwpLCB4PXgsIHk9LTEwLCBjb2xvdXI9YmF0Y2gpKSArCiAgbGFicyh4PSIiLCB5PSIiLCB0aXRsZT0iQ2x1c3RlcmluZzogc2FtcGxlcyBjb2xvcmVkIGJ5IEJhdGNoIikKcGRfY29uZCA8LSBnZ3Bsb3Qoc2VnbWVudChkZGF0YSkpICsgCiAgZ2VvbV9zZWdtZW50KGFlcyh4PXgsIHk9eSwgeGVuZD14ZW5kLCB5ZW5kPXllbmQpKSArIAogIGNvb3JkX2ZsaXAoKSArIHNjYWxlX3lfcmV2ZXJzZSgpICsKICBnZW9tX3RleHQoZGF0YT10bXAsIGFlcyhsYWJlbD1hcy5jaGFyYWN0ZXIodG1wJGxhYmVsKSwgeD14LCB5PS0xMCwgY29sb3VyPWNvbmQpKSArCiAgbGFicyh4PSIiLCB5PSIiLCB0aXRsZT0iQ2x1c3RlcmluZzogc2FtcGxlcyBjb2xvcmVkIGJ5IENvbmRpdGlvbiIpCmdyaWQuYXJyYW5nZShwZF9iYXRjaCwgcGRfY29uZCwgbmNvbD0yKQoKcm0oY291bnRzX25vcm0sIGRkYXRhLCBkZW5kLCBoYywgcF9iYXRjaCwgcF9jb25kLCBwY2Ffb2JqLCBwZF9iYXRjaCwgcGRfY29uZCwgdG1wKQpgYGAKCgojIyBMaWJyYXJ5IHNpemUKCk5leHQsIHdlIHRha2UgYSBsb29rIGF0IHRoZSBvYnNlcnZlZCBsaWJyYXJ5IHNpemVzIG9mIHNhbXBsZXMsIGFuZCB0byBzZWUgaWYgdGhlcmUgaXMgYSBkaWZmZXJlbmNlIGluIGxpYnJhcnkgc2l6ZSBhY3Jvc3MgYmF0Y2hlcy4KCmBgYHtyLCBlY2hvPUZBTFNFfQojIyMgIERpc3RyaWJ1dGlvbiBvZiBsaWJyYXJ5IHNpemUKbGliX3NpemVzIDwtIGNvbFN1bXMoY3RzX21hdCkKY2F0KCJSYW5nZSBvZiBvYnNlcnZlZCBsaWJyYXJ5IHNpemVzIGFjcm9zcyBzYW1wbGVzOlxuIikKcHJpbnQoc2NpZW50aWZpYyhyYW5nZShsaWJfc2l6ZXMpKSkKYGBgCgpgYGB7ciwgZWNobz1GQUxTRSwgZmlnLmhlaWdodD0yLCBmaWcud2lkdGg9NH0KbGliX3NpemVzX2RmIDwtIGRhdGEuZnJhbWUobGliX3NpemVzPWxpYl9zaXplcywgYmF0Y2g9YXMuZmFjdG9yKGJhdGNoKSkKCiMgb3ZlcmFsbCBzYW1wbGUgbGlicmFyeSBzaXplcwpwbGliMSA8LSBnZ3Bsb3QobGliX3NpemVzX2RmLCBhZXMoeD1saWJfc2l6ZXMpKSArIAogIGdlb21faGlzdG9ncmFtKGJpbnM9cm91bmQobmNvbChzaWdkYXRhKS81KSkgKwogIGdlb21fdmxpbmUoYWVzKHhpbnRlcmNlcHQ9bWVhbihsaWJfc2l6ZXMpKSwgY29sb3I9InJlZCIsIGxpbmV0eXBlPSJkYXNoZWQiLCBzaXplPTEpICsKICBhbm5vdGF0ZShnZW9tPSJ0ZXh0IiwgeD1tZWFuKGxpYl9zaXplcyksIHk9bWF4KGhpc3QobGliX3NpemVzLCBwbG90PUZBTFNFKSRjb3VudHMpKzEsIAogICAgICAgICAgIGxhYmVsPXNjaWVudGlmaWMobWVhbihsaWJfc2l6ZXMpKSwgY29sb3I9InJlZCIpICsKICBsYWJzKHg9IkxpYnJhcnkgc2l6ZXMgaW4gc2FtcGxlcyIsIHk9Ik51bWJlciBvZiBzYW1wbGVzIiwgCiAgICAgICB0aXRsZT0iRGlzdHJpYnV0aW9uIG9mIG9ic2VydmVkIGxpYnJhcnkgc2l6ZXMiKSAKCiMgYm94cGxvdCBjb21wYXJpbmcgZGlzdHJpYnV0aW9uIG9mIGxpYnJhcnkgc2l6ZSBhY3Jvc3MgYmF0Y2hlcwpwbGliMiA8LSBnZ3Bsb3QobGliX3NpemVzX2RmLCBhZXMoeD1iYXRjaCwgeT1saWJfc2l6ZXMsIGZpbGw9YmF0Y2gpKSArIAogIGdlb21fYm94cGxvdCgpICsKICBsYWJzKHg9IiIsIHk9IkxpYnJhcnkgc2l6ZXMiLCB0aXRsZT0iQ29tcGFyZSBsaWJyYXJ5IHNpemVzIGFjcm9zcyBiYXRjaCIpIAoKZ3JpZC5hcnJhbmdlKHBsaWIxLCBwbGliMiwgbmNvbD0yKQoKcm0ocGxpYjEsIHBsaWIyKQpgYGAKCgojIyBHZW5lIGV4cHJlc3Npb24gZGlzdHJpYnV0aW9uCgpPdXIgbmV4dCBzdGVwIGlzIHRvIGludGVycm9nYXRlIHRoZSBnZW5lIGV4cHJlc3Npb24gZGlzdHJpYnV0aW9ucy4gCgpXZSBmaXJzdCBzaW1wbHkgcGxvdCB0aGUgY291bnRzLCBDUE0sIGFuZCBsb2cyQ1BNIG9mIDIwIHJhbmRvbWx5IGNob3NlbiBnZW5lcyBpbiB0aGUgZGF0YXNldC4gVGhlc2UgZmlndXJlcyBhcmUgc3RvcmVkIHVuZGVyIGRpcmVjdG9yeSBzcGVjaWZpZWQgYnkgb3V0cHV0X2Rpci4gIAoKYGBge3IsIGVjaG89RkFMU0UsIHJlc3VsdHM9J2hpZGUnLCBldmFsPUZBTFNFfQppZighZGlyLmV4aXN0cyhmaWxlLnBhdGgob3V0cHV0X2RpciwgInJhbmRHcGxvdHMiKSkpe2Rpci5jcmVhdGUoZmlsZS5wYXRoKG91dHB1dF9kaXIsICJyYW5kR3Bsb3RzIikpfQpzZXQuc2VlZCgxMjMpCk5fc2VsIDwtIDIwCmNob3Nlbl9pZCA8LSBzYW1wbGUoMTpucm93KGN0c19tYXQpLCBOX3NlbCwgcmVwbGFjZT1GQUxTRSkKCmN0c19zdWJzZXQgPC0gY3RzX21hdFtjaG9zZW5faWQsIF0KY3BtX3N1YnNldCA8LSBjcG0oY3RzX21hdCwgbG9nPUZBTFNFKVtjaG9zZW5faWQsIF0KbG9nQ1BNX3N1YnNldCA8LSBjcG0oY3RzX21hdCwgbG9nPVRSVUUpW2Nob3Nlbl9pZCwgXQpkYXRhX2xzdCA8LSBsaXN0KENvdW50cz1jdHNfc3Vic2V0LCBDUE09Y3BtX3N1YnNldCwgbG9nMkNQTT1sb2dDUE1fc3Vic2V0KQoKdm9pZCA8LSBtYXBwbHkoZnVuY3Rpb24oZGF0LCBkYXRfbmFtZSwgbWV0YV9pbmZvKXsKICBmb3IoaSBpbiAxOm5yb3coZGF0KSl7CiAgICAjIHByZXBhcmUgZGF0YSBmcmFtZQogICAgY3Vycl9kZiA8LSBkYXRhLmZyYW1lKHNhbXBsZXM9Y29sbmFtZXMoZGF0KSwgdmFsdWU9ZGF0W2ksIF0pCiAgICBjdXJyX2RmIDwtIG1lcmdlKHg9Y3Vycl9kZiwgeT1tZXRhX2luZm8sIGJ5Lng9InNhbXBsZXMiLCBieS55PSJzYW1wbGUiKQogICAgCiAgICAjIHNjYXR0ZXIgcGxvdCBmb3IgaS10aCBnZW5lCiAgICBwX3NjYXR0ZXIgPC0gZ2dwbG90KGN1cnJfZGYsIGFlcyh4PXNhbXBsZXMsIHk9dmFsdWUsIGNvbG9yPWNvbmQsIHNoYXBlPWJhdGNoKSkgKwogICAgICBnZW9tX3BvaW50KCkgKwogICAgICBsYWJzKHg9IlNhbXBsZXMiLCB5PWRhdF9uYW1lLCB0aXRsZT1wYXN0ZTAoImdlbmUiLCBjaG9zZW5faWRbaV0pKSArCiAgICAgIHRoZW1lKGF4aXMudGV4dC54PWVsZW1lbnRfYmxhbmsoKSkKICAgIAogICAgIyB2aW9saW4gcGxvdCBmb3IgaS10aCBnZW5lCiAgICBwX3Zpb2xpbiA8LSBnZ3Bsb3QoY3Vycl9kZiwgYWVzKDAsIHZhbHVlKSkgKyAKICAgICAgZ2VvbV92aW9saW4oKSArCiAgICAgIGdlb21fYm94cGxvdCh3aWR0aD0wLjIpICsKICAgICAgY29vcmRfZmxpcCgpICsKICAgICAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1hcy5pbnRlZ2VyKG1lZGlhbihjdXJyX2RmJHZhbHVlKSksIHg9MC4xMiwgeT1tZWRpYW4oY3Vycl9kZiR2YWx1ZSkpKSArCiAgICAgIGxhYnMoeT1kYXRfbmFtZSwgdGl0bGU9c3ByaW50ZigiQWxsIHNhbXBsZXMsICVzIiwgcm93bmFtZXMoZGF0KVtpXSkpICsKICAgICAgdGhlbWUoYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSkKICAgIAogICAgIyB2aW9saW4gcGxvdCBncm91cCBieSBiYXRjaAogICAgbWVkaWFuc19iYXRjaCA8LSBhZ2dyZWdhdGUodmFsdWUgfiBiYXRjaCwgZGF0YT1jdXJyX2RmLCBGVU49bWVkaWFuKQogICAgcF92aW9saW5fYmF0Y2ggPC0gZ2dwbG90KGN1cnJfZGYsIGFlcyh4PWJhdGNoLCB5PXZhbHVlLCBjb2xvcj1iYXRjaCkpICsgCiAgICAgIGdlb21fdmlvbGluKCkgKwogICAgICBnZW9tX2JveHBsb3Qod2lkdGg9MC4yKSArCiAgICAgIGNvb3JkX2ZsaXAoKSArCiAgICAgICNzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoJyNFNjlGMDAnLCAnIzU2QjRFOScpKSArCiAgICAgIGdlb21fdGV4dChkYXRhPW1lZGlhbnNfYmF0Y2gsIAogICAgICAgICAgICAgICAgYWVzKGxhYmVsPXJvdW5kKG1lZGlhbnNfYmF0Y2gkdmFsdWUsMiksIHg9YXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIobWVkaWFuc19iYXRjaCRiYXRjaCkpKzAuMTIsCiAgICAgICAgICAgICAgICAgICAgeT1hcy5udW1lcmljKGFzLmNoYXJhY3RlcihtZWRpYW5zX2JhdGNoJHZhbHVlKSkpKSArCiAgICAgIGxhYnMoeT1kYXRfbmFtZSwgdGl0bGU9c3ByaW50ZigiSW4gYmF0Y2hlcywgJXMiLCByb3duYW1lcyhkYXQpW2ldKSkgKwogICAgICB0aGVtZShheGlzLnRpdGxlLnk9ZWxlbWVudF9ibGFuaygpKQogICAgCiAgICAjIHZpb2xpbiBwbG90IGdyb3VwIGJ5IGNvbmRpdGlvbgogICAgbWVkaWFuc19jb25kIDwtIGFnZ3JlZ2F0ZSh2YWx1ZSB+IGNvbmQsIGRhdGE9Y3Vycl9kZiwgRlVOPW1lZGlhbikKICAgIHBfdmlvbGluX2NvbmQgPC0gZ2dwbG90KGN1cnJfZGYsIGFlcyh4PWNvbmQsIHk9dmFsdWUsIGNvbG9yPWNvbmQpKSArIAogICAgICBnZW9tX3Zpb2xpbigpICsKICAgICAgZ2VvbV9ib3hwbG90KHdpZHRoPTAuMikgKwogICAgICBjb29yZF9mbGlwKCkgKwogICAgICBnZW9tX3RleHQoZGF0YT1tZWRpYW5zX2NvbmQsCiAgICAgICAgICAgICAgICBhZXMobGFiZWw9cm91bmQobWVkaWFuc19jb25kJHZhbHVlLDIpLCB4PWFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKG1lZGlhbnNfY29uZCRjb25kKSkrMS4xMiwgCiAgICAgICAgICAgICAgICAgICAgeT1hcy5udW1lcmljKGFzLmNoYXJhY3RlcihtZWRpYW5zX2NvbmQkdmFsdWUpKSkpICsKICAgICAgbGFicyh5PWRhdF9uYW1lLCB0aXRsZT1zcHJpbnRmKCJJbiBjb25kaXRpb24gZ3JvdXBzLCAlcyIsIHJvd25hbWVzKGRhdClbaV0pKSArCiAgICAgIHRoZW1lKGF4aXMudGl0bGUueT1lbGVtZW50X2JsYW5rKCkpCiAgICAKICAgICMgb3V0cHV0IHBsb3QKICAgIHBuZyhzcHJpbnRmKCIlcy8lc19nZW5lJXMucG5nIiwgZmlsZS5wYXRoKG91dHB1dF9kaXIsICJyYW5kR3Bsb3RzIiksIGRhdF9uYW1lLCBpKSwKICAgICAgICB3aWR0aD0xMCwgaGVpZ2h0PTgsIHVuaXRzPSJpbiIsIHJlcz0zMDApCiAgICBncmlkLmFycmFuZ2UocF9zY2F0dGVyLCBwX3Zpb2xpbiwgcF92aW9saW5fYmF0Y2gsIHBfdmlvbGluX2NvbmQsIG5yb3c9MiwgbmNvbD0yKQogICAgZGV2Lm9mZigpCiAgfQp9LCBkYXQ9ZGF0YV9sc3QsIGRhdF9uYW1lPW5hbWVzKGRhdGFfbHN0KSwgbWV0YV9pbmZvPWxpc3QobWV0YV9pbmZvLG1ldGFfaW5mbyxtZXRhX2luZm8pKQoKcm0oY3RzX3N1YnNldCwgY3BtX3N1YnNldCwgbG9nQ1BNX3N1YnNldCwgbGliX3NpemVzLCBsaWJfc2l6ZXNfZGYsIGNob3Nlbl9pZCwgZGF0YV9sc3QsIHZvaWQsIE5fc2VsKQpgYGAKCgojIyMgRm9sZCBjaGFuZ2VzIGluIG1lYW4gey50YWJzZXR9CgpXZSB0aGVuIHVzZSBlZGdlUiB0byBwZXJmb3JtIGRpZmZlcmVudGlhbCBleHByZXNzaW9uIGFuYWx5c2lzLCBhbmQgY2FsY3VsYXRlIChsb2ctKSBmb2xkIGNoYW5nZXMgb2YgYWxsIGdlbmVzIGJldHdlZW4gY29uZGl0aW9uIGdyb3VwcyBhbmQgYmF0Y2hlcy4KCiMjIyMgQ2hhbmdlIFdSVCBjb25kaXRpb24KClRvIHJ1bGUgb3V0IHRoZSBpbXBhY3Qgb2YgYmF0Y2ggZWZmZWN0LCB3ZSBsaW1pdCBvdXIgREUgYW5hbHlzaXMgd2l0aCByZWdhcmQgdG8gYmlvbG9naWNhbCBjb25kaXRpb24gaW4gb25lIG9mIHRoZSBiYXRjaGVzLiBIZXJlIHdlIHNwZWNpZnkgdGhlIGJhdGNoIHRvIGJlICoqQmF0Y2ggMjogRUdGUiB2cyBHRlAgY29udHJvbCoqLgoKYGBge3IsIHJlc3VsdHM9ImhpZGUifQojIyMjICBEaWZmZXJlbnRpYWwgZ2VuZXMgcmVsYXRpdmUgdG8gYmlvbG9naWNhbCBjb25kaXRpb24gCiMjIyMgICh3aXRoaW4gYmF0Y2ggc3BlY2lmaWVkIGJ5ICd0ZXN0X2JhdGNoJykKdGVzdF9iYXRjaCA8LSAyCmNvdW50c19iYXRjaCA8LSBjdHNfbWF0WywgYmF0Y2g9PXRlc3RfYmF0Y2hdCmNvbmRfYmF0Y2ggPC0gZ3JvdXBfbnVtW2JhdGNoPT10ZXN0X2JhdGNoXQoKeSA8LSBER0VMaXN0KGNvdW50cz1jb3VudHNfYmF0Y2gsIGdyb3VwPWFzLmZhY3Rvcihjb25kX2JhdGNoKSkKeSA8LSBjYWxjTm9ybUZhY3RvcnMoeSwgbWV0aG9kPSJUTU0iKQpkZXNpZ24gPC0gbW9kZWwubWF0cml4KH5hcy5mYWN0b3IoY29uZF9iYXRjaCkpCnkgPC0gZXN0aW1hdGVEaXNwKHksIGRlc2lnbikKZml0IDwtIGdsbVFMRml0KHksIGRlc2lnbikKcWxmIDwtIGdsbVFMRlRlc3QoZml0LCBjb2VmPTIpCmRlX3JlcyA8LSB0b3BUYWdzKHFsZiwgbj1ucm93KHNpZ2RhdGEpKQogCnVwX2dlbmVzIDwtIHJvd25hbWVzKGRlX3Jlcylbd2hpY2goZGVfcmVzJHRhYmxlJGxvZ0ZDID49IDApXSAgIyBhbGwgdXAtcmVndWxhdGVkIGdlbmVzIChkZXNjZW5kaW5nIG9yZGVyIGluIHRlcm1zIG9mIHAgdmFsdWUpCmhlYWRfdXBfZ2VuZXMgPC0gaGVhZCh1cF9nZW5lcywgbj01MCkgICMgdG9wLTUwIHNpZ25pZmljYW50IHVwLXJlZ3VsYXRlZCBnZW5lcwp0YWlsX3VwX2dlbmVzIDwtIHRhaWwodXBfZ2VuZXMsIG49NTApICAjIDUwIGxlYXN0IHNpZ25pZmljYW50IHVwLXJlZ3VsYXRlZCBnZW5lcwoKY29uZF91cF9pbmRzIDwtIHVwX2dlbmVzIAoKZG93bl9nZW5lcyA8LSByb3duYW1lcyhkZV9yZXMpW3doaWNoKGRlX3JlcyR0YWJsZSRsb2dGQyA8IDApXSAgIyBhbGwgZG93bi1yZWd1bGF0ZWQgZ2VuZXMKaGVhZF9kb3duX2dlbmVzIDwtIGhlYWQoZG93bl9nZW5lcywgbj01MCkgICMgdG9wLTUwIHNpZ25pZmljYW50IGRvd24tcmVndWxhdGVkIGdlbmVzCnRhaWxfZG93bl9nZW5lcyA8LSB0YWlsKGRvd25fZ2VuZXMsIG49NTApICAjIDUwIGxlYXN0IHNpZ25pZmljYW50IGRvd24tcmVndWxhdGVkIGdlbmVzCgpjb25kX2Rvd25faW5kcyA8LSBkb3duX2dlbmVzCmBgYAoKYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiMgY2hhbmdlcyBpbiB0ZXJtcyBvZiBtZWFuCmNhdCgiIyMjIyMjICBDaGFuZ2VzIGluIHRlcm1zIG9mIGF2ZXJhZ2UgZ2VuZSBjb3VudHMgICMjIyMjI1xuIikKbWVhbl9jdHNfbWF0IDwtIG1hdHJpeChOQSwgbnJvdz0yLCBuY29sPTMsIAogICAgICAgICAgICAgICAgICAgICAgIGRpbW5hbWVzPWxpc3QoYygiR0ZQIiwgIkVHRlIiKSwgYygidG9wNTAgdXAiLCAidG9wNTAgZG93biIsICIxMDAgbGVhc3QgREUiKSkpCm1lYW5fY3RzX21hdFsiR0ZQIiwgInRvcDUwIHVwIl0gPC0gbWVhbihjb3VudHNfYmF0Y2hbaGVhZF91cF9nZW5lcywgY29uZF9iYXRjaD09MF0pCm1lYW5fY3RzX21hdFsiRUdGUiIsICJ0b3A1MCB1cCJdIDwtIG1lYW4oY291bnRzX2JhdGNoW2hlYWRfdXBfZ2VuZXMsIGNvbmRfYmF0Y2g9PTNdKQptZWFuX2N0c19tYXRbIkdGUCIsICJ0b3A1MCBkb3duIl0gPC0gbWVhbihjb3VudHNfYmF0Y2hbaGVhZF9kb3duX2dlbmVzLCBjb25kX2JhdGNoPT0wXSkKbWVhbl9jdHNfbWF0WyJFR0ZSIiwgInRvcDUwIGRvd24iXSA8LSBtZWFuKGNvdW50c19iYXRjaFtoZWFkX2Rvd25fZ2VuZXMsIGNvbmRfYmF0Y2g9PTNdKQptZWFuX2N0c19tYXRbIkdGUCIsICIxMDAgbGVhc3QgREUiXSA8LSBtZWFuKGNvdW50c19iYXRjaFtjKHRhaWxfdXBfZ2VuZXMsIHRhaWxfZG93bl9nZW5lcyksIGNvbmRfYmF0Y2g9PTBdKQptZWFuX2N0c19tYXRbIkVHRlIiLCAiMTAwIGxlYXN0IERFIl0gPC0gbWVhbihjb3VudHNfYmF0Y2hbYyh0YWlsX3VwX2dlbmVzLCB0YWlsX2Rvd25fZ2VuZXMpLCBjb25kX2JhdGNoPT0zXSkKcHJpbnQocm91bmQobWVhbl9jdHNfbWF0LDEpKQoKIyBjaGFuZ2VzIGluIHRlcm1zIG9mIChsb2cpIGZvbGQgY2hhbmdlCmNhdCgiXG4jIyMjIyMgIFJhbmdlIG9mIGZvbGQgY2hhbmdlIGFjcm9zcyBiaW9sb2dpY2FsIGNvbmRpdGlvbnMgICMjIyMjI1xuIikKRkNfbWF0IDwtIG1hdHJpeChOQSwgbnJvdz00LCBuY29sPTMsIAogICAgICAgICAgICAgICAgIGRpbW5hbWVzPWxpc3QoYygibWluIEZDIiwgIm1lZGlhbiBGQyIsICJtZWFuIEZDIiwgIm1heCBGQyIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoInRvcDUwIHVwIiwgInRvcDUwIGRvd24iLCAiMTAwIGxlYXN0IERFIikpKQpGQ19tYXRbLCAidG9wNTAgdXAiXSA8LSBzYXBwbHkoYyhtaW4sIG1lZGlhbiwgbWVhbiwgbWF4KSwgZnVuY3Rpb24oZmYpe2ZmKGV4cChkZV9yZXMkdGFibGVbaGVhZF91cF9nZW5lcywgImxvZ0ZDIl0pKX0pCkZDX21hdFssICJ0b3A1MCBkb3duIl0gPC0gc2FwcGx5KGMobWluLCBtZWRpYW4sIG1lYW4sIG1heCksIGZ1bmN0aW9uKGZmKXtmZihleHAoZGVfcmVzJHRhYmxlW2hlYWRfZG93bl9nZW5lcywgImxvZ0ZDIl0pKX0pCkZDX21hdFssICIxMDAgbGVhc3QgREUiXSA8LSBzYXBwbHkoYyhtaW4sIG1lZGlhbiwgbWVhbiwgbWF4KSwgZnVuY3Rpb24oZmYpewogIGZmKGV4cChkZV9yZXMkdGFibGVbYyh0YWlsX3VwX2dlbmVzLCB0YWlsX2Rvd25fZ2VuZXMpLCAibG9nRkMiXSkpCn0pCnByaW50KHJvdW5kKEZDX21hdCwzKSkKCmNhdCgiXG4jIyMjIyMgIFJhbmdlIG9mIExvZyhmb2xkIGNoYW5nZSkgYWNyb3NzIGJpb2xvZ2ljYWwgY29uZGl0aW9ucyAgIyMjIyMjXG4iKQpsb2dGQ19tYXQgPC0gbG9nKEZDX21hdCkKcm93bmFtZXMobG9nRkNfbWF0KSA8LSBjKCJtaW4gbG9nRkMiLCAibWVkaWFuIGxvZ0ZDIiwgIm1lYW4gbG9nRkMiLCAibWF4IGxvZ0ZDIikKcHJpbnQocm91bmQobG9nRkNfbWF0LDMpKQoKCiMgdmlzdWFsaXplIGNoYW5nZSBpbiB0ZXJtcyBvZiAobG9nKSBmb2xkIGNoYW5nZQpsb2dGQ19kZiA8LSBkYXRhLmZyYW1lKHRvcDUwdXA9ZGVfcmVzJHRhYmxlW2hlYWRfdXBfZ2VuZXMsICJsb2dGQyJdLCB0b3A1MGRvd249ZGVfcmVzJHRhYmxlW2hlYWRfZG93bl9nZW5lcywgImxvZ0ZDIl0pCkZDX2RmIDwtIGV4cChsb2dGQ19kZikKcF9sb2dGQyA8LSBnZ3Bsb3QobWVsdChsb2dGQ19kZiksIGFlcyh4PXZhcmlhYmxlLCB5PXZhbHVlKSkgKwogIGdlb21fYm94cGxvdCgpICsKICBsYWJzKHk9ImxvZ0ZDIikgKwogIHRoZW1lKGF4aXMudGl0bGUueD1lbGVtZW50X2JsYW5rKCkpCnBfRkMgPC0gZ2dwbG90KG1lbHQoRkNfZGYpLCBhZXMoeD12YXJpYWJsZSwgeT12YWx1ZSkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgbGFicyh5PSJGQyIpICsKICB0aGVtZShheGlzLnRpdGxlLng9ZWxlbWVudF9ibGFuaygpKQpncmlkLmFycmFuZ2UocF9sb2dGQywgcF9GQywgbmNvbD0yKQpgYGAKCmBgYHtyLCBlY2hvPUZBTFNFLCByZXN1bHRzPSdoaWRlJ30Kcm0oY29uZF9iYXRjaCwgY291bnRzX2JhdGNoLCB1cF9nZW5lcywgaGVhZF91cF9nZW5lcywgdGFpbF91cF9nZW5lcywgCiAgIGRvd25fZ2VuZXMsIGhlYWRfZG93bl9nZW5lcywgdGFpbF9kb3duX2dlbmVzLCB5LCBkZXNpZ24sIGZpdCwgcWxmLCBkZV9yZXMsIAogICBtZWFuX2N0c19tYXQsIEZDX21hdCwgcF9GQywgcF9sb2dGQywgRkNfZGYsIGxvZ0ZDX2RmLCBsb2dGQ19tYXQpCmBgYAoKKipDb25jbHVzaW9uczoqKgoKKyBCaW9sb2dpY2FsIGZvbGQgY2hhbmdlIGNvbXBhcmluZyBhdmVyYWdlIGNvdW50cyAqKmluIHRvcCBERSBnZW5lcyoqIGlzIGFib3V0IDEuMy0xLjQuIAorIEdlbmUtd2lzZSBmb2xkIGNoYW5nZSByYW5nZXMgKippbiB0b3AgREUgZ2VuZXMqKiBmcm9tIDEuNy0xLjguCgoKIyMjIyBDaGFuZ2UgV1JUIGJhdGNoCgpXZSBhcmUgYWxzbyBpbnRlcmVzdGVkIHRvIHNlZSBob3cgdGhlIGF2ZXJhZ2UgKG1lYW4pIGdlbmUgY291bnRzIGNoYW5nZSBhY3Jvc3MgYmF0Y2hlcyAoaS5lLiAqKmRlZ3JlZSBvZiBtZWFuIGJhdGNoIGVmZmVjdCoqKS4gCgpUbyBleHBsb3JlIHRoaXMgbWVhbiBiYXRjaCBlZmZlY3QsIHdlICoqZmlyc3QgcGVyZm9ybSBERSB3aXRoIHJlZ2FyZCB0byB0aGUgYmF0Y2ggdmFyaWFibGUqKi4gVG8gcnVsZSBvdXQgdGhlIGltcGFjdCBvZiBiaW9sb2dpY2FsIGNvbmRpdGlvbiwgd2UgcGVyZm9ybSB0aGlzIGFuYWx5c2lzIHdpdGhpbiAqKmNvbnRyb2wqKiBzYW1wbGVzIG9ubHkuIFNpbmNlIGZyb20gdGhlIFBDQSBwbG90LCBCYXRjaCAyIHNlcGFyYXRlcyBmcm9tIHRoZSBvdGhlciB0d28gYmF0Y2hlcyBtb3JlLCB3ZSBjb21wYXJlICoqQmF0Y2ggMSBhbmQgMioqIGluIHRoaXMgY2FzZS4KCmBgYHtyLCByZXN1bHRzPSJoaWRlIn0KIyMjIyAgRGlmZmVyZW50aWFsIGdlbmVzIHJlbGF0aXZlIHRvIGJhdGNoIAojIyMjICAod2l0aGluIGNvbmRpdGlvbiAwIC8gY29uZGl0aW9uIHNwZWNpZmllZCBieSAndGVzdF9jb25kJykKdGVzdF9jb25kIDwtIDAKY291bnRzX2NvbmQgPC0gY3RzX21hdFssIChncm91cF9udW09PXRlc3RfY29uZCkgJiAoYmF0Y2ghPTMpXQpiYXRjaF9jb25kIDwtIGJhdGNoWyhncm91cF9udW09PXRlc3RfY29uZCkgJiAoYmF0Y2ghPTMpXQoKeSA8LSBER0VMaXN0KGNvdW50cz1jb3VudHNfY29uZCwgZ3JvdXA9YXMuZmFjdG9yKGJhdGNoX2NvbmQpKQp5IDwtIGNhbGNOb3JtRmFjdG9ycyh5LCBtZXRob2Q9IlRNTSIpCmRlc2lnbiA8LSBtb2RlbC5tYXRyaXgofmFzLmZhY3RvcihiYXRjaF9jb25kKSkKeSA8LSBlc3RpbWF0ZURpc3AoeSwgZGVzaWduKQpmaXQgPC0gZ2xtUUxGaXQoeSwgZGVzaWduKQpxbGYgPC0gZ2xtUUxGVGVzdChmaXQsIGNvZWY9MikKZGVfcmVzIDwtIHRvcFRhZ3MocWxmLCBuPW5yb3coc2lnZGF0YSkpCgp1cF9nZW5lcyA8LSByb3duYW1lcyhkZV9yZXMpW3doaWNoKGRlX3JlcyR0YWJsZSRsb2dGQyA+PSAwKV0gICMgYWxsIHVwLXJlZ3VsYXRlZCBnZW5lcwpoZWFkX3VwX2dlbmVzIDwtIGhlYWQodXBfZ2VuZXMsIG49NTApICAjIHRvcC01MCB1cC1yZWd1bGF0ZWQgZ2VuZXMKdGFpbF91cF9nZW5lcyA8LSB0YWlsKHVwX2dlbmVzLCBuPTUwKSAgIyA1MCBsZWFzdCB1cC1yZWd1bGF0ZWQgZ2VuZXMKCmJhdGNoX3VwX2luZHMgPC0gdXBfZ2VuZXMKCmRvd25fZ2VuZXMgPC0gcm93bmFtZXMoZGVfcmVzKVt3aGljaChkZV9yZXMkdGFibGUkbG9nRkMgPCAwKV0gICMgYWxsIGRvd24tcmVndWxhdGVkIGdlbmVzCmhlYWRfZG93bl9nZW5lcyA8LSBoZWFkKGRvd25fZ2VuZXMsIG49NTApICAjIHRvcC01MCBkb3duLXJlZ3VsYXRlZCBnZW5lcwp0YWlsX2Rvd25fZ2VuZXMgPC0gdGFpbChkb3duX2dlbmVzLCBuPTUwKSAgIyA1MCBsZWFzdCBkb3duLXJlZ3VsYXRlZCBnZW5lcwoKYmF0Y2hfZG93bl9pbmRzIDwtIGRvd25fZ2VuZXMKYGBgCgpgYGB7ciwgZWNobz1GQUxTRX0KIyBjaGFuZ2VzIGluIHRlcm1zIG9mIG1lYW4KY2F0KCIjIyMjIyMgIEJhdGNoIGRpZmZlcmVuY2VzIGluIHRlcm1zIG9mIG1lYW4gZ2VuZSBjb3VudHMgICMjIyMjI1xuIikKbWVhbl9jdHNfbWF0IDwtIG1hdHJpeChOQSwgbnJvdz0yLCBuY29sPTMsIAogICAgICAgICAgICAgICAgICAgICAgIGRpbW5hbWVzPWxpc3QoYygiQmF0Y2gxIiwgIkJhdGNoMiIpLCBjKCJ0b3A1MCB1cCIsICJ0b3A1MCBkb3duIiwgIjEwMCBsZWFzdCBjaGFuZ2VkIikpKQptZWFuX2N0c19tYXRbIkJhdGNoMSIsICJ0b3A1MCB1cCJdIDwtIG1lYW4oY291bnRzX2NvbmRbaGVhZF91cF9nZW5lcywgYmF0Y2hfY29uZD09MV0pCm1lYW5fY3RzX21hdFsiQmF0Y2gyIiwgInRvcDUwIHVwIl0gPC0gbWVhbihjb3VudHNfY29uZFtoZWFkX3VwX2dlbmVzLCBiYXRjaF9jb25kPT0yXSkKbWVhbl9jdHNfbWF0WyJCYXRjaDEiLCAidG9wNTAgZG93biJdIDwtIG1lYW4oY291bnRzX2NvbmRbaGVhZF9kb3duX2dlbmVzLCBiYXRjaF9jb25kPT0xXSkKbWVhbl9jdHNfbWF0WyJCYXRjaDIiLCAidG9wNTAgZG93biJdIDwtIG1lYW4oY291bnRzX2NvbmRbaGVhZF9kb3duX2dlbmVzLCBiYXRjaF9jb25kPT0yXSkKbWVhbl9jdHNfbWF0WyJCYXRjaDEiLCAiMTAwIGxlYXN0IGNoYW5nZWQiXSA8LSBtZWFuKGNvdW50c19jb25kW2ModGFpbF91cF9nZW5lcywgdGFpbF9kb3duX2dlbmVzKSwgYmF0Y2hfY29uZD09MV0pCm1lYW5fY3RzX21hdFsiQmF0Y2gyIiwgIjEwMCBsZWFzdCBjaGFuZ2VkIl0gPC0gbWVhbihjb3VudHNfY29uZFtjKHRhaWxfdXBfZ2VuZXMsIHRhaWxfZG93bl9nZW5lcyksIGJhdGNoX2NvbmQ9PTJdKQpwcmludChyb3VuZChtZWFuX2N0c19tYXQsMSkpCgojIGNoYW5nZXMgaW4gdGVybXMgb2YgZm9sZCBjaGFuZ2UKY2F0KCJcbiMjIyMjIyAgUmFuZ2Ugb2YgZm9sZCBjaGFuZ2UgYmV0d2VlbiBiYXRjaGVzICAjIyMjIyNcbiIpCmNhdCgiLSBBbGwgZ2VuZXMgLSBGQzpcbiIpCmNhdChyb3VuZChyYW5nZShleHAoZGVfcmVzJHRhYmxlJGxvZ0ZDKSksIDMpKSAKCmNhdCgiXG5cbi0gQWxsIGdlbmVzIC0gbG9nKEZDKTpcbiIpCmNhdChyb3VuZChyYW5nZShkZV9yZXMkdGFibGUkbG9nRkMpLCAzKSkgCgpjYXQoIlxuXG4tIFRvcCBnZW5lcyAtIEZDOlxuIikKRkNfbWF0IDwtIG1hdHJpeChOQSwgbnJvdz00LCBuY29sPTMsIAogICAgICAgICAgICAgICAgIGRpbW5hbWVzPWxpc3QoYygibWluIEZDIiwgIm1lZGlhbiBGQyIsICJtZWFuIEZDIiwgIm1heCBGQyIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoInRvcDUwIHVwIiwgInRvcDUwIGRvd24iLCAiMTAwIGxlYXN0IERFIikpKQpGQ19tYXRbLCAidG9wNTAgdXAiXSA8LSBzYXBwbHkoYyhtaW4sIG1lZGlhbiwgbWVhbiwgbWF4KSwgZnVuY3Rpb24oZmYpe2ZmKGV4cChkZV9yZXMkdGFibGVbaGVhZF91cF9nZW5lcywgImxvZ0ZDIl0pKX0pCkZDX21hdFssICJ0b3A1MCBkb3duIl0gPC0gc2FwcGx5KGMobWluLCBtZWRpYW4sIG1lYW4sIG1heCksIGZ1bmN0aW9uKGZmKXtmZihleHAoZGVfcmVzJHRhYmxlW2hlYWRfZG93bl9nZW5lcywgImxvZ0ZDIl0pKX0pCkZDX21hdFssICIxMDAgbGVhc3QgREUiXSA8LSBzYXBwbHkoYyhtaW4sIG1lZGlhbiwgbWVhbiwgbWF4KSwgZnVuY3Rpb24oZmYpewogIGZmKGV4cChkZV9yZXMkdGFibGVbYyh0YWlsX3VwX2dlbmVzLCB0YWlsX2Rvd25fZ2VuZXMpLCAibG9nRkMiXSkpCn0pCnByaW50KHJvdW5kKEZDX21hdCwzKSkKCmNhdCgiXG4tIFRvcCBnZW5lcyAtIGxvZyhGQyk6XG4iKQpsb2dGQ19tYXQgPC0gbG9nKEZDX21hdCkKcm93bmFtZXMobG9nRkNfbWF0KSA8LSBjKCJtaW4gbG9nRkMiLCAibWVkaWFuIGxvZ0ZDIiwgIm1lYW4gbG9nRkMiLCAibWF4IGxvZ0ZDIikKcHJpbnQocm91bmQobG9nRkNfbWF0LDMpKQoKYGBgCgpgYGB7ciwgZWNobz1GQUxTRSwgcmVzdWx0cz0naGlkZSd9CnJtKGJhdGNoX2NvbmQsIGNvdW50c19jb25kLCB1cF9nZW5lcywgaGVhZF91cF9nZW5lcywgdGFpbF91cF9nZW5lcywgCiAgIGRvd25fZ2VuZXMsIGhlYWRfZG93bl9nZW5lcywgdGFpbF9kb3duX2dlbmVzLCB5LCBkZXNpZ24sIGZpdCwgcWxmLCBkZV9yZXMsIAogICBtZWFuX2N0c19tYXQsIEZDX21hdCwgbG9nRkNfbWF0KQpgYGAKCioqQ29uY2x1c2lvbjoqKgoKKyBNZWFuIGJhdGNoIGVmZmVjdCBmb2xkIGNoYW5nZSBjb21wYXJpbmcgYXZlcmFnZSBjb3VudHMgKippbiB0b3AgZ2VuZXMqKiBpcyBxdWl0ZSBsYXJnZS4gKipCdXQgcmVtZW1iZXIsIHRoZXNlIGFyZSB0b3AgZ2VuZXMgdGhhdCBjaGFuZ2UgYWNyb3NzIGJhdGNoZXMqKi4KCgojIyMgQmF0Y2ggbWVhbgoKKipNZWRpYW4gKG9mIGFsbCBnZW5lcykqKiBnZW5lLXdpc2UgbWVhbjogCgpgYGB7ciwgZWNobz1GQUxTRX0KbWVhbl90YiA8LSBtYXRyaXgoTkEsIG5yb3c9MiwgbmNvbD1ubGV2ZWxzKGFzLmZhY3RvcihiYXRjaCkpLCAKICAgICAgICAgICAgICAgICBkaW1uYW1lcz1saXN0KGMoIkNvbnRyb2xzIiwgIkNhc2VzIiksIHBhc3RlMCgiQmF0Y2giLCBsZXZlbHMoYXMuZmFjdG9yKGJhdGNoKSkpKSkKbWVhbl90YlsiQ29udHJvbHMiLCAiQmF0Y2gxIl0gPC0gbWVkaWFuKHJvd01lYW5zKGFzc2F5KHNpZ2RhdGEsImNvdW50cyIpWywgYmF0Y2g9PTEmZ3JvdXA9PSJnZnAxOCJdKSkKbWVhbl90YlsiQ2FzZXMiLCAiQmF0Y2gxIl0gPC0gbWVkaWFuKHJvd01lYW5zKGFzc2F5KHNpZ2RhdGEsImNvdW50cyIpWywgYmF0Y2g9PTEmZ3JvdXA9PSJiYWQiXSkpCm1lYW5fdGJbIkNvbnRyb2xzIiwgIkJhdGNoMiJdIDwtIG1lZGlhbihyb3dNZWFucyhhc3NheShzaWdkYXRhLCJjb3VudHMiKVssIGJhdGNoPT0yJmdyb3VwPT0iZ2ZwX2Zvcl9lZ2ZyIl0pKQptZWFuX3RiWyJDYXNlcyIsICJCYXRjaDIiXSA8LSBtZWRpYW4ocm93TWVhbnMoYXNzYXkoc2lnZGF0YSwiY291bnRzIilbLCBiYXRjaD09MiZncm91cD09ImVnZnIiXSkpCm1lYW5fdGJbIkNvbnRyb2xzIiwgIkJhdGNoMyJdIDwtIG1lZGlhbihyb3dNZWFucyhhc3NheShzaWdkYXRhLCJjb3VudHMiKVssIGJhdGNoPT0zJmdyb3VwPT0iZ2ZwMzAiXSkpCm1lYW5fdGJbIkNhc2VzIiwgIkJhdGNoMyJdIDwtIG1lZGlhbihyb3dNZWFucyhhc3NheShzaWdkYXRhLCJjb3VudHMiKVssIGJhdGNoPT0zJmdyb3VwPT0ia3Jhc3d0Il0pKQpwcmludChyb3VuZChtZWFuX3RiLCAyKSkKYGBgCgpTY2FsZWQgYnkgdGhhdCBvZiBiYXRjaCAxOgoKYGBge3IsIGVjaG89RkFMU0V9Cm1lYW5fdGJfc2NhbGVkIDwtIGFwcGx5KG1lYW5fdGIsIDIsIGZ1bmN0aW9uKHgpe3gvbWVhbl90YlssIkJhdGNoMSJdfSkKcHJpbnQocm91bmQobWVhbl90Yl9zY2FsZWQsIDIpKQpgYGAKCgojIyMgQmF0Y2ggZGlzcGVyc2lvbgoKQXNpZGUgZnJvbSBhdmVyYWdlIGdlbmUgY291bnRzLCB3ZSBhcmUgaW50ZXJlc3RlZCBpbiBjb21wYXJpbmcgZGlzcGVyc2lvbnMgaW4gdGhlIGJhdGNoZXMuICoqRGlmZmVyZW5jZSBpbiB0aGUgZGlzcGVyc2lvbnMgYWNyb3NzIGJhdGNoZXMgc3VnZ2VzdHMgdmFyaWFuY2UgYmF0Y2ggZWZmZWN0IHRoYXQgYXJlIG5vdCBhY2NvdW50ZWQgZm9yIGJ5IFBvaXNzb24gbW9kZWwqKi4gV2UgdmlzdWFsaXplIHRoZSBnZW5lLXdpc2UgZGlzcGVyc2lvbiBlc3RpbWF0ZXMgZnJvbSBlZGdlUjoKCmBgYHtyLCBlY2hvPUZBTFNFfQojIyMjICBEaXNwZXJzaW9uIGRpZmZlcmVuY2VzIGFjcm9zcyBiYXRjaCAxIGFuZCAyCnlfYmF0Y2gxIDwtIERHRUxpc3QoY291bnRzPWN0c19tYXRbLCBiYXRjaD09MV0sIGdyb3VwPWFzLmZhY3Rvcihncm91cF9udW1bYmF0Y2g9PTFdKSkKeV9iYXRjaDEgPC0gY2FsY05vcm1GYWN0b3JzKHlfYmF0Y2gxLCBtZXRob2Q9IlRNTSIpCmRlc2lnbl9iYXRjaDEgPC0gbW9kZWwubWF0cml4KH5hcy5mYWN0b3IoZ3JvdXBfbnVtW2JhdGNoPT0xXSkpCnlfYmF0Y2gxIDwtIGVzdGltYXRlRGlzcCh5X2JhdGNoMSwgZGVzaWduX2JhdGNoMSkKCnlfYmF0Y2gyIDwtIERHRUxpc3QoY291bnRzPWN0c19tYXRbLCBiYXRjaD09Ml0sIGdyb3VwPWFzLmZhY3Rvcihncm91cF9udW1bYmF0Y2g9PTJdKSkKeV9iYXRjaDIgPC0gY2FsY05vcm1GYWN0b3JzKHlfYmF0Y2gyLCBtZXRob2Q9IlRNTSIpCmRlc2lnbl9iYXRjaDIgPC0gbW9kZWwubWF0cml4KH5hcy5mYWN0b3IoZ3JvdXBfbnVtW2JhdGNoPT0yXSkpCnlfYmF0Y2gyIDwtIGVzdGltYXRlRGlzcCh5X2JhdGNoMiwgZGVzaWduX2JhdGNoMikKCnlfYmF0Y2gzIDwtIERHRUxpc3QoY291bnRzPWN0c19tYXRbLCBiYXRjaD09M10sIGdyb3VwPWFzLmZhY3Rvcihncm91cF9udW1bYmF0Y2g9PTNdKSkKeV9iYXRjaDMgPC0gY2FsY05vcm1GYWN0b3JzKHlfYmF0Y2gzLCBtZXRob2Q9IlRNTSIpCmRlc2lnbl9iYXRjaDMgPC0gbW9kZWwubWF0cml4KH5hcy5mYWN0b3IoZ3JvdXBfbnVtW2JhdGNoPT0zXSkpCnlfYmF0Y2gzIDwtIGVzdGltYXRlRGlzcCh5X2JhdGNoMywgZGVzaWduX2JhdGNoMykKCmRpc3BfZGYgPC0gZGF0YS5mcmFtZShCYXRjaDE9eV9iYXRjaDEkdGFnd2lzZS5kaXNwZXJzaW9uLCBCYXRjaDI9eV9iYXRjaDIkdGFnd2lzZS5kaXNwZXJzaW9uLAogICAgICAgICAgICAgICAgICAgICAgQmF0Y2gzPXlfYmF0Y2gzJHRhZ3dpc2UuZGlzcGVyc2lvbikKCmNhdCgiIyMjIyAgU3RhdGlzdGljcyBhYm91dCBkaXNwZXJzaW9uIGVzdGltYXRlcyBmcm9tIHRoZSBiYXRjaGVzICAjIyMjXG4iKQpkaXNwX3N0YXRzIDwtIGxhcHBseShjKG1pbiwgbWVkaWFuLCBtZWFuLCBtYXgpLCBmdW5jdGlvbihmZil7YXBwbHkoZGlzcF9kZiwgMiwgZmYpfSkKZGlzcF9zdGF0cyA8LSBkby5jYWxsKHJiaW5kLCBkaXNwX3N0YXRzKQpyb3duYW1lcyhkaXNwX3N0YXRzKSA8LSBjKCJtaW4gZGlzcC4iLCAibWVkaWFuIGRpc3AuIiwgIm1lYW4gZGlzcC4iLCAibWF4IGRpc3AuIikKcHJpbnQocm91bmQoZGlzcF9zdGF0cywgNCkpCmBgYAoKYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CmRpc3BfZGZfbWx0IDwtIG1lbHQoZGlzcF9kZikKZ2dwbG90KGRpc3BfZGZfbWx0LCBhZXMoeD12YXJpYWJsZSwgeT12YWx1ZSkpICsKICBnZW9tX3Zpb2xpbigpICsKICBsYWJzKHg9IkJhdGNoIiwgeT0iRXN0aW1hdGVkIGdlbmUtd2lzZSBkaXNwZXJzaW9uIiwgCiAgICAgICB0aXRsZT0iQ29tcGFyaXNvbiBvZiBlc3RpbWF0ZWQgZGlzcGVyc2lvbiBhY3Jvc3MgYmF0Y2hlcyIpICsKICBzdGF0X3N1bW1hcnkoZnVuLnk9bWVhbiwgY29sb3VyPSJkYXJrcmVkIiwgZ2VvbT0icG9pbnQiLCBzaGFwZT0xOCwgc2l6ZT0zKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cz1jKDAsIDAuMTUpKQpgYGAKCioqQ29uY2x1c2lvbnM6KioKCisgTWF4IG1lYW4gZGlzcGVyc2lvbiBkaWZmZXJlbmNlOiBCYXRjaCAyIGlzIGFib3V0IDIgdGltZXMgb2YgdGhvc2UgaW4gQmF0Y2ggMy4gCgoKIyMjIEJhdGNoIHZhcmlhbmNlCgoqKk1lZGlhbiAob2YgYWxsIGdlbmVzKSoqIGdlbmUtd2lzZSB2YXJpYW5jZTogCgpgYGB7ciwgZWNobz1GQUxTRX0KdmFyX3RiIDwtIG1hdHJpeChOQSwgbnJvdz0yLCBuY29sPW5sZXZlbHMoYXMuZmFjdG9yKGJhdGNoKSksIAogICAgICAgICAgICAgICAgIGRpbW5hbWVzPWxpc3QoYygiQ29udHJvbHMiLCAiQ2FzZXMiKSwgcGFzdGUwKCJCYXRjaCIsIGxldmVscyhhcy5mYWN0b3IoYmF0Y2gpKSkpKQp2YXJfdGJbIkNvbnRyb2xzIiwgIkJhdGNoMSJdIDwtIG1lZGlhbihyb3dWYXJzKGFzc2F5KHNpZ2RhdGEsImNvdW50cyIpWywgYmF0Y2g9PTEmZ3JvdXA9PSJnZnAxOCJdKSkKdmFyX3RiWyJDYXNlcyIsICJCYXRjaDEiXSA8LSBtZWRpYW4ocm93VmFycyhhc3NheShzaWdkYXRhLCJjb3VudHMiKVssIGJhdGNoPT0xJmdyb3VwPT0icmFmIl0pKQp2YXJfdGJbIkNvbnRyb2xzIiwgIkJhdGNoMiJdIDwtIG1lZGlhbihyb3dWYXJzKGFzc2F5KHNpZ2RhdGEsImNvdW50cyIpWywgYmF0Y2g9PTImZ3JvdXA9PSJnZnBfZm9yX2VnZnIiXSkpCnZhcl90YlsiQ2FzZXMiLCAiQmF0Y2gyIl0gPC0gbWVkaWFuKHJvd1ZhcnMoYXNzYXkoc2lnZGF0YSwiY291bnRzIilbLCBiYXRjaD09MiZncm91cD09ImVnZnIiXSkpCnZhcl90YlsiQ29udHJvbHMiLCAiQmF0Y2gzIl0gPC0gbWVkaWFuKHJvd1ZhcnMoYXNzYXkoc2lnZGF0YSwiY291bnRzIilbLCBiYXRjaD09MyZncm91cD09ImdmcDMwIl0pKQp2YXJfdGJbIkNhc2VzIiwgIkJhdGNoMyJdIDwtIG1lZGlhbihyb3dWYXJzKGFzc2F5KHNpZ2RhdGEsImNvdW50cyIpWywgYmF0Y2g9PTMmZ3JvdXA9PSJrcmFzZ3YiXSkpCnByaW50KHJvdW5kKHZhcl90YiwgMikpCmBgYAoKU2NhbGVkIGJ5IHRoYXQgb2YgYmF0Y2ggMToKCmBgYHtyLCBlY2hvPUZBTFNFfQp2YXJfdGJfc2NhbGVkIDwtIGFwcGx5KHZhcl90YiwgMiwgZnVuY3Rpb24oeCl7eC92YXJfdGJbLCJCYXRjaDEiXX0pCnByaW50KHJvdW5kKHZhcl90Yl9zY2FsZWQsIDIpKQpgYGAKCgojIyBJbXBhY3Qgb2YgMCBjb3VudHMgb24gZ2VuZSBkaXN0cmlidXRpb25zCgpXZSBoYXZlIHNlZW4gdGhhdCBhIGxvdCBvZiBnZW5lcyBpbiB0aGUgZGF0YXNldCBjb250YWluIHNvbWUgcG9ydGlvbiBvZiB6ZXJvcy4gSGF2aW5nIDAgY291bnRzIGNhbiBoYXZlIGEgZ3JlYXQgaW1wYWN0IG9uIG1lYW4gYW5kIGRpc3BlcnNpb24gZXN0aW1hdGlvbi4gV2UgZXZhbHVhdGUgc3VjaCBpbXBhY3QgaW4gdGhpcyBzZWN0aW9uLCBhbmQgc2VlIGhvdyBOQiBkaXN0cmlidXRpb24gZml0cyB0byBub24temVybyBwb3J0aW9uIG9mIGdlbmVzLiBXZSBmaXJzdCB0YWtlIHRoZSBub24temVybyBwb3J0aW9uIG9mIHRoZSBnZW5lcy4KCiMjIyBGb2xkIGNoYW5nZSBpbiBtZWFuIGluIG5vbi16ZXJvIHBvcnRpb24gey50YWJzZXR9CgpgYGB7ciwgZWNobz1GQUxTRX0KY3RzIDwtIGN0c19tYXQKCiMgdGFrZSB0aGUgbm9uLXplcm8gcG9ydGlvbiBpbiBlYWNoIGdlbmUKYmF0Y2hfc2VwIDwtIGdyb3VwX3NlcCA8LSBub256ZXJvX2N0cyA8LSBsaXN0KCkKZm9yKGkgaW4gMTpucm93KGN0cykpewogIG5vbnplcm9faW5kIDwtIHdoaWNoKGN0c1tpLCBdIT0wKQogIGJhdGNoX3NlcFtbaV1dIDwtIGJhdGNoW25vbnplcm9faW5kXQogIGdyb3VwX3NlcFtbaV1dIDwtIGdyb3VwX251bVtub256ZXJvX2luZF0KICBub256ZXJvX2N0c1tbaV1dIDwtIGN0c1tpLCBub256ZXJvX2luZF0KfQojIHNhbml0eSBjaGVjawppZighaWRlbnRpY2FsKHNhcHBseShub256ZXJvX2N0cywgbGVuZ3RoKSwgYXMuaW50ZWdlcihyb3dTdW1zKGN0cyE9MCkpKSl7c3RvcCgiRXJyb3IgaW4gdGFraW5nIG5vbi16ZXJvIHBvcnRpb25zISIpfQoKbmFtZXMobm9uemVyb19jdHMpIDwtIHJvd25hbWVzKGN0cyk7IG5hbWVzKGJhdGNoX3NlcCkgPC0gcm93bmFtZXMoY3RzKTsgbmFtZXMoZ3JvdXBfc2VwKSA8LSByb3duYW1lcyhjdHMpCmBgYAoKIyMjIyAgQ2hhbmdlIFdSVCBjb25kaXRpb24gaW4gYmF0Y2ggMgoKV2l0aGluICoqYmF0Y2ggMioqLCB3ZSBjb21wYXJlIG1lYW4gKGhlcmUgcmVmZXJzIHRvIG5vbi16ZXJvIG1lYW4pIGFjcm9zcyBiaW9sb2dpY2FsIGNvbmRpdGlvbiBncm91cHMuIFNwZWNpZmljYWxseSwgKip3ZSBzYXZlZCB0aGUgcHJldmlvdXMgREUgYW5hbHlzaXMgcmVzdWx0cyB1c2luZyBlZGdlUiwgb24gY291bnRzIGNvbnRhaW5pbmcgemVyb3MqKi4gV2UgY2FsbCBhbGwgZ2VuZXMgd2l0aCAkXGxvZyhGQykgPj0gMCQgYXMgInVwIiBnZW5lcywgYW5kICRcbG9nKEZDKSA8IDAkIGFzICJkb3duIiBnZW5lcy4gVGhlIHRvcCA1MCAidXAiIGFuZCAiZG93biIgZ2VuZXMgKHdpdGggc21hbGxlc3QgcCB2YWx1ZXMpIGFyZSBzdGlsbCBkZXRlcm1pbmVkIGJ5IHRoZSBwcmV2aW91cyBERSBjb250YWluaW5nIHplcm9zLgoKYGBge3IsIGVjaG89RkFMU0V9CiMgdGFrZSBiYXRjaCAyCmdyb3VwX3NlcF9iYXRjaDIgPC0gbm9uemVyb19jdHNfYmF0Y2gyIDwtIGxpc3QoKQpmb3IoaSBpbiAxOmxlbmd0aChub256ZXJvX2N0cykpewogIGdyb3VwX3NlcF9iYXRjaDJbW2ldXSA8LSBncm91cF9zZXBbW2ldXVtiYXRjaF9zZXBbW2ldXT09Ml0KICBub256ZXJvX2N0c19iYXRjaDJbW2ldXSA8LSBub256ZXJvX2N0c1tbaV1dW2JhdGNoX3NlcFtbaV1dPT0yXQp9Cm5hbWVzKG5vbnplcm9fY3RzX2JhdGNoMikgPC0gbmFtZXMoZ3JvdXBfc2VwX2JhdGNoMikgPC0gcm93bmFtZXMoY3RzKQoKIyBzcGxpdCBpbnRvIGNvbnRyb2xzICYgY2FzZXMKbm9uemVyb19jdHNfYjJfY3RybHMgPC0gbm9uemVyb19jdHNfYjJfY2FzZXMgPC0gbGlzdCgpCmZvcihqIGluIDE6bGVuZ3RoKG5vbnplcm9fY3RzX2JhdGNoMikpewogIG5vbnplcm9fY3RzX2IyX2N0cmxzW1tqXV0gPC0gbm9uemVyb19jdHNfYmF0Y2gyW1tqXV1bZ3JvdXBfc2VwX2JhdGNoMltbal1dPT0wXQogIG5vbnplcm9fY3RzX2IyX2Nhc2VzW1tqXV0gPC0gbm9uemVyb19jdHNfYmF0Y2gyW1tqXV1bZ3JvdXBfc2VwX2JhdGNoMltbal1dPT0zXQp9I2lkZW50aWNhbChzYXBwbHkobm9uemVyb19jdHNfYjJfY3RybHMsIGxlbmd0aCkgKyBzYXBwbHkobm9uemVyb19jdHNfYjJfY2FzZXMsIGxlbmd0aCksIHNhcHBseShub256ZXJvX2N0c19iYXRjaDIsbGVuZ3RoKSkKbmFtZXMobm9uemVyb19jdHNfYjJfY3RybHMpIDwtIG5hbWVzKG5vbnplcm9fY3RzX2IyX2Nhc2VzKSA8LSByb3duYW1lcyhjdHMpCgojIHRvcCA1MCB1cCBhbmQgZG93biBpbmRpY2VzCnRvcF91cF9pbmQgPC0gaGVhZChjb25kX3VwX2luZHMsIDUwKQp0b3BfZG93bl9pbmQgPC0gaGVhZChjb25kX2Rvd25faW5kcywgNTApCmxlYXN0X2RlX2luZCA8LSBjKHRhaWwoY29uZF91cF9pbmRzLCA1MCksIHRhaWwoY29uZF9kb3duX2luZHMsIDUwKSkKCiMgY2FsY3VsYXRlIG1lYW4gaW4gdG9wIHVwLCBkb3duIGFuZCBsZWFzdCBERQpjYXQoIiMjIyMjIyAgQ2hhbmdlcyBpbiBNRUFOIG5vbi16ZXJvIGdlbmUgY291bnRzICAjIyMjIyNcbiIpCm1lYW5fbm9uemVyb2N0c19tYXQgPC0gbWF0cml4KE5BLCBucm93PTIsIG5jb2w9MywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpbW5hbWVzPWxpc3QoYygiR0ZQIiwgIkVHRlIiKSwgYygidG9wNTAgdXAiLCAidG9wNTAgZG93biIsICIxMDAgbGVhc3QgREUiKSkpCm1lYW5fbm9uemVyb2N0c19tYXRbIkdGUCIsICJ0b3A1MCB1cCJdIDwtIG1lYW4oZG8uY2FsbChjLCBub256ZXJvX2N0c19iMl9jdHJsc1t0b3BfdXBfaW5kXSkpCm1lYW5fbm9uemVyb2N0c19tYXRbIkVHRlIiLCAidG9wNTAgdXAiXSA8LSBtZWFuKGRvLmNhbGwoYywgbm9uemVyb19jdHNfYjJfY2FzZXNbdG9wX3VwX2luZF0pKQptZWFuX25vbnplcm9jdHNfbWF0WyJHRlAiLCAidG9wNTAgZG93biJdIDwtIG1lYW4oZG8uY2FsbChjLCBub256ZXJvX2N0c19iMl9jdHJsc1t0b3BfZG93bl9pbmRdKSkKbWVhbl9ub256ZXJvY3RzX21hdFsiRUdGUiIsICJ0b3A1MCBkb3duIl0gPC0gbWVhbihkby5jYWxsKGMsIG5vbnplcm9fY3RzX2IyX2Nhc2VzW3RvcF9kb3duX2luZF0pKQptZWFuX25vbnplcm9jdHNfbWF0WyJHRlAiLCAiMTAwIGxlYXN0IERFIl0gPC0gbWVhbihkby5jYWxsKGMsIG5vbnplcm9fY3RzX2IyX2N0cmxzW2xlYXN0X2RlX2luZF0pKQptZWFuX25vbnplcm9jdHNfbWF0WyJFR0ZSIiwgIjEwMCBsZWFzdCBERSJdIDwtIG1lYW4oZG8uY2FsbChjLCBub256ZXJvX2N0c19iMl9jYXNlc1tsZWFzdF9kZV9pbmRdKSkKcHJpbnQocm91bmQobWVhbl9ub256ZXJvY3RzX21hdCwxKSkKYGBgCgpgYGB7cixlY2hvPUZBTFNFfQpjYXQoIiMjIyMjIyAgQ2hhbmdlcyBpbiBNRURJQU4gbm9uLXplcm8gZ2VuZSBjb3VudHMgICMjIyMjI1xuIikKbWVkaWFuX25vbnplcm9jdHNfbWF0IDwtIG1hdHJpeChOQSwgbnJvdz0yLCBuY29sPTMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaW1uYW1lcz1saXN0KGMoIkdGUCIsICJFR0ZSIiksIGMoInRvcDUwIHVwIiwgInRvcDUwIGRvd24iLCAiMTAwIGxlYXN0IERFIikpKQptZWRpYW5fbm9uemVyb2N0c19tYXRbIkdGUCIsICJ0b3A1MCB1cCJdIDwtIG1lZGlhbihkby5jYWxsKGMsIG5vbnplcm9fY3RzX2IyX2N0cmxzW3RvcF91cF9pbmRdKSkKbWVkaWFuX25vbnplcm9jdHNfbWF0WyJFR0ZSIiwgInRvcDUwIHVwIl0gPC0gbWVkaWFuKGRvLmNhbGwoYywgbm9uemVyb19jdHNfYjJfY2FzZXNbdG9wX3VwX2luZF0pKQptZWRpYW5fbm9uemVyb2N0c19tYXRbIkdGUCIsICJ0b3A1MCBkb3duIl0gPC0gbWVkaWFuKGRvLmNhbGwoYywgbm9uemVyb19jdHNfYjJfY3RybHNbdG9wX2Rvd25faW5kXSkpCm1lZGlhbl9ub256ZXJvY3RzX21hdFsiRUdGUiIsICJ0b3A1MCBkb3duIl0gPC0gbWVkaWFuKGRvLmNhbGwoYywgbm9uemVyb19jdHNfYjJfY2FzZXNbdG9wX2Rvd25faW5kXSkpCm1lZGlhbl9ub256ZXJvY3RzX21hdFsiR0ZQIiwgIjEwMCBsZWFzdCBERSJdIDwtIG1lZGlhbihkby5jYWxsKGMsIG5vbnplcm9fY3RzX2IyX2N0cmxzW2xlYXN0X2RlX2luZF0pKQptZWRpYW5fbm9uemVyb2N0c19tYXRbIkVHRlIiLCAiMTAwIGxlYXN0IERFIl0gPC0gbWVkaWFuKGRvLmNhbGwoYywgbm9uemVyb19jdHNfYjJfY2FzZXNbbGVhc3RfZGVfaW5kXSkpCnByaW50KHJvdW5kKG1lZGlhbl9ub256ZXJvY3RzX21hdCwxKSkKYGBgCgoqKkNvbmNsdXNpb25zOiAqKiAKCisgQmlvbG9naWNhbCBmb2xkIGNoYW5nZSAoaW4gbm9uLXplcm8gcG9ydGlvbikgY29tcGFyaW5nIGF2ZXJhZ2UgY291bnRzICoqaW4gdG9wIGdlbmVzKiogaXMgYWJvdXQgMS4zLTEuNCAobWVhbiksIDEuMzkgLSAxLjQyIChtZWRpYW4pLioqCisgTyBjb3VudHMgZGlkIG5vdCBzdHJvbmdseSBhZmZlY3QgYmlvbG9naWNhbCBzaWduYWwgaW4gdGVybXMgb2YgYXZlcmFnZSBjb3VudHMgKippbiB0b3AgZ2VuZXMqKi4KCgojIyMjICBDaGFuZ2UgV1JUIGJhdGNoIGluIGNvbnRyb2wgc2FtcGxlcwoKU2ltaWxhcmx5LCB3ZSBjb21wYXJlIG5vbi16ZXJvIG1lYW4gKippbiB0b3AgZ2VuZXMqKiBhY3Jvc3MgYmF0Y2hlcyB3aXRoaW4gY29udHJvbCBzYW1wbGVzLiBIZXJlIOKAnHRvcCBnZW5lc+KAnSByZWZlciB0byB0b3AgZ2VuZSBsaXN0cyBmcm9tIHByZXZpb3VzIERFIHdpdGhpbiBjb250cm9sIHNhbXBsZXMgY29tcGFyaW5nIGJhdGNoZXMuCgpgYGB7ciwgZWNobz1GQUxTRX0KIyB0YWtlIGNvbnRyb2xzCmJhdGNoX3NlcF9jb25kMCA8LSBub256ZXJvX2N0c19jb25kMCA8LSBsaXN0KCkKZm9yKGkgaW4gMTpsZW5ndGgobm9uemVyb19jdHMpKXsKICBiYXRjaF9zZXBfY29uZDBbW2ldXSA8LSBiYXRjaF9zZXBbW2ldXVtncm91cF9zZXBbW2ldXT09MF0KICBub256ZXJvX2N0c19jb25kMFtbaV1dIDwtIG5vbnplcm9fY3RzW1tpXV1bZ3JvdXBfc2VwW1tpXV09PTBdCn0KbmFtZXMoYmF0Y2hfc2VwX2NvbmQwKSA8LSBuYW1lcyhub256ZXJvX2N0c19jb25kMCkgPC0gcm93bmFtZXMoY3RzKQoKIyBzcGxpdCBpbnRvIGJhdGNoIDEgJiAyCm5vbnplcm9fY3RzX2NvbmQwX2JhdGNoMSA8LSBub256ZXJvX2N0c19jb25kMF9iYXRjaDIgPC0gbGlzdCgpCmZvcihqIGluIDE6bGVuZ3RoKG5vbnplcm9fY3RzKSl7CiAgbm9uemVyb19jdHNfY29uZDBfYmF0Y2gxW1tqXV0gPC0gbm9uemVyb19jdHNfY29uZDBbW2pdXVtiYXRjaF9zZXBfY29uZDBbW2pdXT09MV0KICBub256ZXJvX2N0c19jb25kMF9iYXRjaDJbW2pdXSA8LSBub256ZXJvX2N0c19jb25kMFtbal1dW2JhdGNoX3NlcF9jb25kMFtbal1dPT0yXQp9Cm5hbWVzKG5vbnplcm9fY3RzX2NvbmQwX2JhdGNoMSkgPC0gbmFtZXMobm9uemVyb19jdHNfY29uZDBfYmF0Y2gyKSA8LSByb3duYW1lcyhjdHMpCgojIHRvcCA1MCB1cCBhbmQgZG93biBpbmRpY2VzCnRvcF91cF9pbmQgPC0gaGVhZChiYXRjaF91cF9pbmRzLCA1MCkKdG9wX2Rvd25faW5kIDwtIGhlYWQoYmF0Y2hfZG93bl9pbmRzLCA1MCkKbGVhc3RfZGVfaW5kIDwtIGModGFpbChiYXRjaF91cF9pbmRzLCA1MCksIHRhaWwoYmF0Y2hfZG93bl9pbmRzLCA1MCkpCgojIGNhbGN1bGF0ZSBtZWFuIGluIHRvcCB1cCwgZG93biBhbmQgbGVhc3QgREUKY2F0KCIjIyMjIyMgIENoYW5nZXMgaW4gTUVBTiBub24temVybyBnZW5lIGNvdW50cyAgIyMjIyMjXG4iKQptZWFuX25vbnplcm9jdHNfbWF0IDwtIG1hdHJpeChOQSwgbnJvdz0yLCBuY29sPTMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaW1uYW1lcz1saXN0KGMoIkJhdGNoIDEiLCAiQmF0Y2ggMiIpLCBjKCJ0b3A1MCB1cCIsICJ0b3A1MCBkb3duIiwgIjEwMCBsZWFzdCBERSIpKSkKbWVhbl9ub256ZXJvY3RzX21hdFsiQmF0Y2ggMSIsICJ0b3A1MCB1cCJdIDwtIG1lYW4oZG8uY2FsbChjLCBub256ZXJvX2N0c19jb25kMF9iYXRjaDFbdG9wX3VwX2luZF0pKQptZWFuX25vbnplcm9jdHNfbWF0WyJCYXRjaCAyIiwgInRvcDUwIHVwIl0gPC0gbWVhbihkby5jYWxsKGMsIG5vbnplcm9fY3RzX2NvbmQwX2JhdGNoMlt0b3BfdXBfaW5kXSkpCm1lYW5fbm9uemVyb2N0c19tYXRbIkJhdGNoIDEiLCAidG9wNTAgZG93biJdIDwtIG1lYW4oZG8uY2FsbChjLCBub256ZXJvX2N0c19jb25kMF9iYXRjaDFbdG9wX2Rvd25faW5kXSkpCm1lYW5fbm9uemVyb2N0c19tYXRbIkJhdGNoIDIiLCAidG9wNTAgZG93biJdIDwtIG1lYW4oZG8uY2FsbChjLCBub256ZXJvX2N0c19jb25kMF9iYXRjaDJbdG9wX2Rvd25faW5kXSkpCm1lYW5fbm9uemVyb2N0c19tYXRbIkJhdGNoIDEiLCAiMTAwIGxlYXN0IERFIl0gPC0gbWVhbihkby5jYWxsKGMsIG5vbnplcm9fY3RzX2NvbmQwX2JhdGNoMVtsZWFzdF9kZV9pbmRdKSkKbWVhbl9ub256ZXJvY3RzX21hdFsiQmF0Y2ggMiIsICIxMDAgbGVhc3QgREUiXSA8LSBtZWFuKGRvLmNhbGwoYywgbm9uemVyb19jdHNfY29uZDBfYmF0Y2gyW2xlYXN0X2RlX2luZF0pKQpwcmludChyb3VuZChtZWFuX25vbnplcm9jdHNfbWF0LDEpKQpgYGAKCmBgYHtyLCBlY2hvPUZBTFNFfQojIGNhbGN1bGF0ZSBtZWRpYW4gaW4gdG9wIHVwLCBkb3duIGFuZCBsZWFzdCBERQpjYXQoIiMjIyMjIyAgQ2hhbmdlcyBpbiBNRURJQU4gbm9uLXplcm8gZ2VuZSBjb3VudHMgICMjIyMjI1xuIikKbWVkaWFuX25vbnplcm9jdHNfbWF0IDwtIG1hdHJpeChOQSwgbnJvdz0yLCBuY29sPTMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpbW5hbWVzPWxpc3QoYygiQmF0Y2ggMSIsICJCYXRjaCAyIiksIGMoInRvcDUwIHVwIiwgInRvcDUwIGRvd24iLCAiMTAwIGxlYXN0IERFIikpKQptZWRpYW5fbm9uemVyb2N0c19tYXRbIkJhdGNoIDEiLCAidG9wNTAgdXAiXSA8LSBtZWRpYW4oZG8uY2FsbChjLCBub256ZXJvX2N0c19jb25kMF9iYXRjaDFbdG9wX3VwX2luZF0pKQptZWRpYW5fbm9uemVyb2N0c19tYXRbIkJhdGNoIDIiLCAidG9wNTAgdXAiXSA8LSBtZWRpYW4oZG8uY2FsbChjLCBub256ZXJvX2N0c19jb25kMF9iYXRjaDJbdG9wX3VwX2luZF0pKQptZWRpYW5fbm9uemVyb2N0c19tYXRbIkJhdGNoIDEiLCAidG9wNTAgZG93biJdIDwtIG1lZGlhbihkby5jYWxsKGMsIG5vbnplcm9fY3RzX2NvbmQwX2JhdGNoMVt0b3BfZG93bl9pbmRdKSkKbWVkaWFuX25vbnplcm9jdHNfbWF0WyJCYXRjaCAyIiwgInRvcDUwIGRvd24iXSA8LSBtZWRpYW4oZG8uY2FsbChjLCBub256ZXJvX2N0c19jb25kMF9iYXRjaDJbdG9wX2Rvd25faW5kXSkpCm1lZGlhbl9ub256ZXJvY3RzX21hdFsiQmF0Y2ggMSIsICIxMDAgbGVhc3QgREUiXSA8LSBtZWRpYW4oZG8uY2FsbChjLCBub256ZXJvX2N0c19jb25kMF9iYXRjaDFbbGVhc3RfZGVfaW5kXSkpCm1lZGlhbl9ub256ZXJvY3RzX21hdFsiQmF0Y2ggMiIsICIxMDAgbGVhc3QgREUiXSA8LSBtZWRpYW4oZG8uY2FsbChjLCBub256ZXJvX2N0c19jb25kMF9iYXRjaDJbbGVhc3RfZGVfaW5kXSkpCnByaW50KHJvdW5kKG1lZGlhbl9ub256ZXJvY3RzX21hdCwxKSkKYGBgCgoqKkNvbmNsdXNpb25zOioqIAoKKyBNZWFuIGJhdGNoIGVmZmVjdCBmb2xkIGNoYW5nZSBjb21wYXJpbmcgYXZlcmFnZSBjb3VudHMgKippbiB0b3AgZ2VuZXMqKiBpcyB2ZXJ5IGxhcmdlLgorIE8gY291bnRzIGRpZCBub3Qgc3Ryb25nbHkgYWZmZWN0IG1lYW4gYmF0Y2ggZWZmZWN0IGluIHRlcm1zIG9mIGF2ZXJhZ2UgY291bnRzICoqaW4gdG9wIGdlbmVzKiouCgoKIyMjIEJhdGNoIG1lYW4gd2l0aCAwIGNvdW50cyByZW1vdmVkIAoKKipNZWRpYW4gKG9mIGFsbCBnZW5lcykqKiBnZW5lLXdpc2UgbWVhbiBhZnRlciByZW1vdmluZyB6ZXJvczogCgpgYGB7ciwgZWNobz1GQUxTRX0KbWVhbl90Yl9ybXplcm8gPC0gbWF0cml4KE5BLCBucm93PTIsIG5jb2w9bmxldmVscyhhcy5mYWN0b3IoYmF0Y2gpKSwgCiAgICAgICAgICAgICAgICAgICAgICAgIGRpbW5hbWVzPWxpc3QoYygiQ29udHJvbHMiLCAiQ2FzZXMiKSwgcGFzdGUwKCJCYXRjaCIsIGxldmVscyhhcy5mYWN0b3IoYmF0Y2gpKSkpKQpjdHNfcm16ZXJvIDwtIGFzc2F5KHNpZ2RhdGEsImNvdW50cyIpOyBjdHNfcm16ZXJvW2N0c19ybXplcm89PTBdIDwtIE5BCm1lYW5fdGJfcm16ZXJvWyJDb250cm9scyIsICJCYXRjaDEiXSA8LSBtZWRpYW4ocm93TWVhbnMoY3RzX3JtemVyb1ssIGJhdGNoPT0xJmdyb3VwPT0iZ2ZwMTgiXSwgbmEucm09VFJVRSksIG5hLnJtPVRSVUUpCm1lYW5fdGJfcm16ZXJvWyJDYXNlcyIsICJCYXRjaDEiXSA8LSBtZWRpYW4ocm93TWVhbnMoY3RzX3JtemVyb1ssIGJhdGNoPT0xJmdyb3VwPT0icmFmIl0sIG5hLnJtPVRSVUUpLCBuYS5ybT1UUlVFKQptZWFuX3RiX3JtemVyb1siQ29udHJvbHMiLCAiQmF0Y2gyIl0gPC0gbWVkaWFuKHJvd01lYW5zKGN0c19ybXplcm9bLCBiYXRjaD09MiZncm91cD09ImdmcF9mb3JfZWdmciJdLCBuYS5ybT1UUlVFKSwgbmEucm09VFJVRSkKbWVhbl90Yl9ybXplcm9bIkNhc2VzIiwgIkJhdGNoMiJdIDwtIG1lZGlhbihyb3dNZWFucyhjdHNfcm16ZXJvWywgYmF0Y2g9PTImZ3JvdXA9PSJlZ2ZyIl0sIG5hLnJtPVRSVUUpLCBuYS5ybT1UUlVFKQptZWFuX3RiX3JtemVyb1siQ29udHJvbHMiLCAiQmF0Y2gzIl0gPC0gbWVkaWFuKHJvd01lYW5zKGN0c19ybXplcm9bLCBiYXRjaD09MyZncm91cD09ImdmcDMwIl0sIG5hLnJtPVRSVUUpLCBuYS5ybT1UUlVFKQptZWFuX3RiX3JtemVyb1siQ2FzZXMiLCAiQmF0Y2gzIl0gPC0gbWVkaWFuKHJvd01lYW5zKGN0c19ybXplcm9bLCBiYXRjaD09MyZncm91cD09ImtyYXNndiJdLCBuYS5ybT1UUlVFKSwgbmEucm09VFJVRSkKcHJpbnQocm91bmQobWVhbl90Yl9ybXplcm8sIDIpKQpgYGAKClNjYWxlZCBieSB0aGF0IG9mIGJhdGNoIDE6CgpgYGB7ciwgZWNobz1GQUxTRX0KbWVhbl90Yl9ybXplcm9fc2NhbGVkIDwtIGFwcGx5KG1lYW5fdGJfcm16ZXJvLCAyLCBmdW5jdGlvbih4KXt4L21lYW5fdGJfcm16ZXJvWywiQmF0Y2gxIl19KQpwcmludChyb3VuZChtZWFuX3RiX3JtemVyb19zY2FsZWQsIDIpKQpgYGAKCgojIyMgQmF0Y2ggZGlzcGVyc2lvbiB3aXRoIDAgY291bnRzIHJlbW92ZWQgCgpEaXNwZXJzaW9uIGVzdGltYXRlcyBhcmUgbW9yZSBsaWtlbHkgaW1wYWN0ZWQgYnkgMCBjb3VudHMuIFdlIHJlLWVzdGltYXRlIHRoZSBkaXNwZXJzaW9ucyBpbiBlYWNoIGJhdGNoLCB1c2luZyBub24temVybyBwb3J0aW9uIG9mIGVhY2ggZ2VuZS4gVGhlbiB3ZSBjb21wYXJlIHRoZSBkaXNwZXJzaW9uIGVzdGltYXRlcyBhY3Jvc3MgYmF0Y2hlcy4KCmBgYHtyLCBlY2hvPUZBTFNFfQpsb2FkKGZpbGUucGF0aChvdXRwdXRfZGlyLCAiZGlzcHNfbm9uemVyby5SRGF0YSIpKQpkaXNwX25vbnplcm9fbHN0IDwtIGxpc3QoQmF0Y2gxPWRpc3Bfbm9uemVyb19iYXRjaDEsIEJhdGNoMj1kaXNwX25vbnplcm9fYmF0Y2gyLCBCYXRjaDM9ZGlzcF9ub256ZXJvX2JhdGNoMykKCmNhdCgiIyMjIyAgU3RhdGlzdGljcyBhYm91dCBkaXNwZXJzaW9uIGVzdGltYXRlcyAoZnJvbSBOT04tWkVSTyBwb3J0aW9ucykgZnJvbSB0aGUgdHdvIGJhdGNoZXMgICMjIyNcbiIpCmRpc3Bfc3RhdHMgPC0gbGFwcGx5KGMobWluLCBtZWRpYW4sIG1lYW4sIG1heCksIGZ1bmN0aW9uKGZmKXtzYXBwbHkoZGlzcF9ub256ZXJvX2xzdCwgZmYpfSkKZGlzcF9zdGF0cyA8LSBkby5jYWxsKHJiaW5kLCBkaXNwX3N0YXRzKQpyb3duYW1lcyhkaXNwX3N0YXRzKSA8LSBjKCJtaW4gZGlzcC4iLCAibWVkaWFuIGRpc3AuIiwgIm1lYW4gZGlzcC4iLCAibWF4IGRpc3AuIikKcHJpbnQocm91bmQoZGlzcF9zdGF0cywgNCkpCmBgYAoKYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CmRpc3Bfbm9uemVyb19kZiA8LSBkYXRhLmZyYW1lKEJhdGNoPWMocmVwKCJCYXRjaDEiLCBsZW5ndGgoZGlzcF9ub256ZXJvX2JhdGNoMSkpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXAoIkJhdGNoMiIsIGxlbmd0aChkaXNwX25vbnplcm9fYmF0Y2gyKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwKCJCYXRjaDMiLCBsZW5ndGgoZGlzcF9ub256ZXJvX2JhdGNoMykpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU9ZG8uY2FsbChjLCBkaXNwX25vbnplcm9fbHN0KSkKZ2dwbG90KGRpc3Bfbm9uemVyb19kZiAsIGFlcyh4PUJhdGNoLCB5PXZhbHVlKSkgKwogIGdlb21fdmlvbGluKCkgKwogIGxhYnMoeD0iQmF0Y2giLCB5PSJFc3RpbWF0ZWQgZ2VuZS13aXNlIGRpc3BlcnNpb24gb24gTk9OLVpFUk8gY291bnRzIiwgCiAgICAgICB0aXRsZT0iQ29tcGFyaXNvbiBvZiBlc3RpbWF0ZWQgZGlzcGVyc2lvbiBhY3Jvc3MgYmF0Y2hlcyIpICsKICBzdGF0X3N1bW1hcnkoZnVuLnk9bWVhbiwgY29sb3VyPSJkYXJrcmVkIiwgZ2VvbT0icG9pbnQiLCBzaGFwZT0xOCwgc2l6ZT0zKSAjKwogICNzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzPWMoMCwgMSkpCmBgYAoKKipDb25jbHVzaW9uczoqKgoKKyBUaGUgYWJzb2x1dGUgdmFsdWUgb2YgbWF4aW11bSBkaXNwZXJzaW9uIGFyZSByZWR1Y2VkIGFmdGVyIDAgY291bnRzIGFyZSByZW1vdmVkLgorIEluIHRoaXMgcmVwb3J0LCBkaXNwZXJzaW9uIGFyZSBjYWxjdWxhdGVkIGJ5IGRpZmZlcmVudCBtZXRob2RzIGJlZm9yZSBhbmQgYWZ0ZXIgcmVtb3ZpbmcgMCBjb3VudHMuICoqTm90IGRpcmVjdGx5IGNvbXBhcmFibGUuKioKKyBXZSBzaG93IGluIGFub3RoZXIgYW5hbHlzaXMgKCpnZnJuU2lnX3J1bl9ub256ZXJvX2Rpc3BzLlIqKSB0aGF0IHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBiYXRjaGVzIGRpZCBub3QgY2hhbmdlIG11Y2ggYWZ0ZXIgcmVtb3ZpbmcgMHMuCgoKIyMjIEJhdGNoIHZhcmlhbmNlIHdpdGggMCBjb3VudHMgcmVtb3ZlZCAKCioqTWVkaWFuKiogZ2VuZS13aXNlIHZhcmlhbmNlIGFmdGVyIHJlbW92aW5nIHplcm9zOiAKCmBgYHtyLCBlY2hvPUZBTFNFfQp2YXJfdGJfcm16ZXJvIDwtIG1hdHJpeChOQSwgbnJvdz0yLCBuY29sPW5sZXZlbHMoYXMuZmFjdG9yKGJhdGNoKSksIAogICAgICAgICAgICAgICAgICAgICAgICBkaW1uYW1lcz1saXN0KGMoIkNvbnRyb2xzIiwgIkNhc2VzIiksIHBhc3RlMCgiQmF0Y2giLCBsZXZlbHMoYXMuZmFjdG9yKGJhdGNoKSkpKSkKY3RzX3JtemVybyA8LSBhc3NheShzaWdkYXRhLCJjb3VudHMiKTsgY3RzX3JtemVyb1tjdHNfcm16ZXJvPT0wXSA8LSBOQQp2YXJfdGJfcm16ZXJvWyJDb250cm9scyIsICJCYXRjaDEiXSA8LSBtZWRpYW4ocm93VmFycyhjdHNfcm16ZXJvWywgYmF0Y2g9PTEmZ3JvdXA9PSJnZnAxOCJdLCBuYS5ybT1UUlVFKSwgbmEucm09VFJVRSkKdmFyX3RiX3JtemVyb1siQ2FzZXMiLCAiQmF0Y2gxIl0gPC0gbWVkaWFuKHJvd1ZhcnMoY3RzX3JtemVyb1ssIGJhdGNoPT0xJmdyb3VwPT0icmFmIl0sIG5hLnJtPVRSVUUpLCBuYS5ybT1UUlVFKQp2YXJfdGJfcm16ZXJvWyJDb250cm9scyIsICJCYXRjaDIiXSA8LSBtZWRpYW4ocm93VmFycyhjdHNfcm16ZXJvWywgYmF0Y2g9PTImZ3JvdXA9PSJnZnBfZm9yX2VnZnIiXSwgbmEucm09VFJVRSksIG5hLnJtPVRSVUUpCnZhcl90Yl9ybXplcm9bIkNhc2VzIiwgIkJhdGNoMiJdIDwtIG1lZGlhbihyb3dWYXJzKGN0c19ybXplcm9bLCBiYXRjaD09MiZncm91cD09ImVnZnIiXSwgbmEucm09VFJVRSksIG5hLnJtPVRSVUUpCnZhcl90Yl9ybXplcm9bIkNvbnRyb2xzIiwgIkJhdGNoMyJdIDwtIG1lZGlhbihyb3dWYXJzKGN0c19ybXplcm9bLCBiYXRjaD09MyZncm91cD09ImdmcDMwIl0sIG5hLnJtPVRSVUUpLCBuYS5ybT1UUlVFKQp2YXJfdGJfcm16ZXJvWyJDYXNlcyIsICJCYXRjaDMiXSA8LSBtZWRpYW4ocm93VmFycyhjdHNfcm16ZXJvWywgYmF0Y2g9PTMmZ3JvdXA9PSJrcmFzZ3YiXSwgbmEucm09VFJVRSksIG5hLnJtPVRSVUUpCnByaW50KHJvdW5kKHZhcl90Yl9ybXplcm8sIDIpKQpgYGAKClNjYWxlZCBieSB0aGF0IG9mIGJhdGNoIDE6CgpgYGB7ciwgZWNobz1GQUxTRX0KdmFyX3RiX3JtemVyb19zY2FsZWQgPC0gYXBwbHkodmFyX3RiX3JtemVybywgMiwgZnVuY3Rpb24oeCl7eC92YXJfdGJfcm16ZXJvWywiQmF0Y2gxIl19KQpwcmludChyb3VuZCh2YXJfdGJfcm16ZXJvX3NjYWxlZCwgMikpCmBgYAoKCiMjIyBJcyB0aGVyZSBhIGRpZmZlcmVuY2UgaW4gemVybyBwb3J0aW9ucyBhY3Jvc3MgYmF0Y2hlcz8KCkFub3RoZXIgcXVlc3Rpb24gcmVsYXRlZCB0byBiYXRjaCBlZmZlY3QsIGlzIHdoZXRoZXIgdGhlcmUgaXMgYW55IGRpZmZlcmVuY2UgaW4gdGhlIHBlcmNlbnRhZ2Ugb2YgMCBjb3VudHMgaW4gYSBnZW5lIGJldHdlZW4gYmF0Y2hlcy4gCgpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KY3RzIDwtIGN0c19tYXQKCm5femVyb3NfYmF0Y2gxIDwtIGFwcGx5KGN0c1ssIGJhdGNoPT0xXSwgMSwgZnVuY3Rpb24oeCl7bGVuZ3RoKHdoaWNoKHg9PTApKX0pCnBlcmNlbnRfemVyb3NfYmF0Y2gxIDwtIG5femVyb3NfYmF0Y2gxIC8gc3VtKGJhdGNoPT0xKQpuX3plcm9zX2JhdGNoMiA8LSBhcHBseShjdHNbLCBiYXRjaD09Ml0sIDEsIGZ1bmN0aW9uKHkpe2xlbmd0aCh3aGljaCh5PT0wKSl9KQpwZXJjZW50X3plcm9zX2JhdGNoMiA8LSBuX3plcm9zX2JhdGNoMiAvIHN1bShiYXRjaD09MikKbl96ZXJvc19iYXRjaDMgPC0gYXBwbHkoY3RzWywgYmF0Y2g9PTNdLCAxLCBmdW5jdGlvbih6KXtsZW5ndGgod2hpY2goej09MCkpfSkKcGVyY2VudF96ZXJvc19iYXRjaDMgPC0gbl96ZXJvc19iYXRjaDMgLyBzdW0oYmF0Y2g9PTMpCgpwZXJjZW50X3plcm9zX2JhdGNoX2RmIDwtIGRhdGEuZnJhbWUoQmF0Y2gxPXBlcmNlbnRfemVyb3NfYmF0Y2gxLCBCYXRjaDI9cGVyY2VudF96ZXJvc19iYXRjaDIsIEJhdGNoMz1wZXJjZW50X3plcm9zX2JhdGNoMykKcGVyY2VudF96ZXJvc19iYXRjaF9kZl9tbHQgPC0gbWVsdChwZXJjZW50X3plcm9zX2JhdGNoX2RmLCB2YXJpYWJsZS5uYW1lPSJCYXRjaCIpCmdncGxvdChwZXJjZW50X3plcm9zX2JhdGNoX2RmX21sdCwgYWVzKHg9QmF0Y2gsIHk9dmFsdWUpKSArCiAgZ2VvbV92aW9saW4oKSArCiAgbGFicyh5PSJQZXJjZW50YWdlIG9mIDAgY291bnRzIGluIGEgc2luZ2xlIGdlbmUiKSArCiAgdGhlbWUoYXhpcy50aXRsZS54PWVsZW1lbnRfYmxhbmsoKSkKYGBgCgoqKkNvbmNsdXNpb25zOioqCgorIFRoZXJlIGlzIGEgY2VydGFpbiBsZXZlbCBvZiBkaWZmZXJlbmNlIGluIHplcm8gZnJhY3Rpb25zIGJldHdlZW4gYmF0Y2hlcy4gU3BlY2lmaWNhbGx5LCBCYXRjaCAzIGhhcyBtb3JlIHJlbGF0aXZlbHkgImNvbXBsZXRlIiAoZmV3ZXIgMCBjb3VudHMpIGdlbmVzIHRoYW4gQmF0Y2hlcyAxICYgMi4gCgoKIyMjIEdvb2RuZXNzIG9mIGZpdCBmb3IgTkIgZGlzdHJpYnV0aW9uIHRvIG5vbi16ZXJvIHBvcnRpb24gb2YgZ2VuZXMKCkl0IGlzIGRpZmZpY3VsdCB0byBldmFsdWF0ZSBxdWFudGl0YXRpdmVseSB0aGUgZ29vZG5lc3Mtb2YtZml0IG9mIE5CIGRpc3RyaWJ1dGlvbiBvbiBkYXRhLiBJbnN0ZWFkLCB3ZSBnZW5lcmF0ZSBRLVEgcGxvdHMgZm9yIDEwMCByYW5kb21seSBzZWxlY3RlZCBnZW5lcywgY29tcGFyaW5nIGRhdGEgd2l0aCBOQiBkaXN0cmlidXRpb24gdXNpbmcgTUwgZXN0aW1hdGVkIHBhcmFtZXRlcnMuIFdlIGdlbmVyYXRlIHRoZXNlIHBsb3RzIHdpdGhpbiAqKmJhdGNoIDIsIGZvciBjYXNlcyBhbmQgY29udHJvbCBzYW1wbGVzIHNlcGFyYXRlbHkqKi4gRmlndXJlcyBhcmUgc3RvcmVkIHVuZGVyIHtvdXRwdXRfZGlyfS9xcXBsb3RzLy4KCmBgYHtyLCBlY2hvPUZBTFNFLCByZXN1bHRzPSJoaWRlIn0KaWYoIWRpci5leGlzdHMoZmlsZS5wYXRoKG91dHB1dF9kaXIsICJxcXBsb3RzIikpKXtkaXIuY3JlYXRlKGZpbGUucGF0aChvdXRwdXRfZGlyLCAicXFwbG90cyIpKX0Kc2V0LnNlZWQoMTIzNCkKTl9zZWxfbmIgPC0gMTAwCmNob3Nlbl9pZF9uYiA8LSBzYW1wbGUoMTpucm93KHNpZ2RhdGEpLCBOX3NlbF9uYiwgcmVwbGFjZT1GQUxTRSkKY3RzX3N1YnNldF9uYiA8LSBjdHNbY2hvc2VuX2lkX25iLCBdCmZvcihpIGluIDE6Tl9zZWxfbmIpewogICMgY2FzZSBzYW1wbGVzCiAgY3Vycl9jdHMgPC0gY3RzX3N1YnNldF9uYltpLCBiYXRjaD09MiAmIGdyb3VwX251bT09M10KICBjdXJyX2N0cyA8LSBjdXJyX2N0c1tjdXJyX2N0cyE9MF0KICBpZihsZW5ndGgodW5pcXVlKGN1cnJfY3RzKSkgPD0gMiB8IHZhcihjdXJyX2N0cyk9PTApe25leHR9CiAgZGYgPC0gZGF0YS5mcmFtZSh5PWN1cnJfY3RzKQogIHBhcmFtcyA8LSBmaXRkaXN0cihkZiR5LCAibmVnYXRpdmUgYmlub21pYWwiKSRlc3RpbWF0ZQogIAogIHBuZyhwYXN0ZTAob3V0cHV0X2RpciwgIi9xcXBsb3RzL2dlbmUiLCBpLCAiX2Nhc2VzLnBuZyIpLCAKICAgICAgd2lkdGg9NSwgaGVpZ2h0PTUsIHVuaXRzPSJpbiIsIHJlcz0zMDApCiAgcHJpbnQoZ2dwbG90KGRmLCBhZXMoc2FtcGxlPXkpKSArCiAgICAgICAgICBzdGF0X3FxKGRpc3RyaWJ1dGlvbj1xbmJpbm9tLCBkcGFyYW1zPXBhcmFtcykgKyAKICAgICAgICAgIHN0YXRfcXFfbGluZShkaXN0cmlidXRpb249cW5iaW5vbSwgZHBhcmFtcz1wYXJhbXMpICsKICAgICAgICAgIGxhYnModGl0bGU9IlEtUSBwbG90OiBCYXRjaCAyIC0gRUdGUiIpKQogIGRldi5vZmYoKQogIHJtKGN1cnJfY3RzLCBkZiwgcGFyYW1zKQogIAogICMgY29udHJvbCBzYW1wbGVzCiAgY3Vycl9jdHMgPC0gY3RzX3N1YnNldF9uYltpLCBiYXRjaD09MiAmIGdyb3VwX251bT09MF0KICBjdXJyX2N0cyA8LSBjdXJyX2N0c1tjdXJyX2N0cyE9MF0KICBpZihsZW5ndGgodW5pcXVlKGN1cnJfY3RzKSkgPD0gMiB8IHZhcihjdXJyX2N0cyk9PTApe25leHR9CiAgZGYgPC0gZGF0YS5mcmFtZSh5PWN1cnJfY3RzKQogIHBhcmFtcyA8LSBmaXRkaXN0cihkZiR5LCAibmVnYXRpdmUgYmlub21pYWwiKSRlc3RpbWF0ZQogIAogIHBuZyhwYXN0ZTAob3V0cHV0X2RpciwgIi9xcXBsb3RzL2dlbmUiLCBpLCAiX2NvbnRyb2xzLnBuZyIpLCAKICAgICAgd2lkdGg9NSwgaGVpZ2h0PTUsIHVuaXRzPSJpbiIsIHJlcz0zMDApCiAgcHJpbnQoZ2dwbG90KGRmLCBhZXMoc2FtcGxlPXkpKSArCiAgICAgICAgICBzdGF0X3FxKGRpc3RyaWJ1dGlvbj1xbmJpbm9tLCBkcGFyYW1zPXBhcmFtcykgKyAKICAgICAgICAgIHN0YXRfcXFfbGluZShkaXN0cmlidXRpb249cW5iaW5vbSwgZHBhcmFtcz1wYXJhbXMpICsKICAgICAgICAgIGxhYnModGl0bGU9IlEtUSBwbG90OiBCYXRjaCAyIC0gR0ZQIikpCiAgZGV2Lm9mZigpCn0KYGBgCgoKIyMgTW9yZSBqdXN0aWZpY2F0aW9uIGZvciBoYXZpbmcgZGlmZmVyZW50IGRpc3BlcnNpb24gcGFyYW1ldGVyIGZvciBkaWZmZXJlbnQgYmF0Y2hlcyB7LnRhYnNldH0KCkZpbmFsbHksIGEgdmVyeSBpbXBvcnRhbnQgYXNzdW1wdGlvbiBvZiBDb21CYXQtc2VxIG1vZGVsIChjb21wYXJlZCB0byBhZGRpbmcgYmF0Y2ggY292YXJpYXRlcyBpbiBsaW5lYXIgbW9kZWwgb2YgZWRnZVIgYW5kIERFU2VxKSwgaXMgdGhhdCAqKmhhdmluZyBhIGRpZmZlcmVudCBkaXNwZXJzaW9uIHBhcmFtZXRlciBmb3IgZWFjaCBiYXRjaCBpcyBiZW5lZmljaWFsIGZvciBERSBwZXJmb3JtYW5jZS4gQXMgYXJndWVkIGJ5IG1hbnksIGlmIG5vdCBhbGwsIG9mIHRoZXNlIHBhcGVycywgYWNjdXJhdGUgZXN0aW1hdGlvbiBvZiBkaXNwZXJzaW9uIHBhcmFtdGVycyBhcmUgaW1wb3J0YW50IGZvciBERSBkZXRlY3Rpb24qKi4gQXMgd2UgaGF2ZSBzZWVuIGFib3ZlLCB0aGVyZSBpcyBzb21lIGRpZmZlcmVuY2UgaW4gZGlzcGVyc2lvbiBkaXN0cmlidXRpb24gYWNyb3NzIGJhdGNoZXMuIElmIGRpc3BlcnNpb24gZXN0aW1hdGVzIHdpdGhpbiBlYWNoIGJhdGNoIGFuZCB1c2luZyB0aGUgd2hvbGUgc3R1ZHkgYXJlIG5vdCBjb25zaXN0ZW50IHdpdGggZWFjaCBvdGhlciwgdGhlbiBpdCBpcyBqdXN0aWZpY2F0aW9uIHRoYXQgd2UgbWF5IG5lZWQgZGlmZmVyZW50IGRpcHNlcnNpb24gcGFyYW1ldGVyIGZvciBkaWZmZXJlbnQgYmF0Y2hlcywgYW5kIGl0IGNvdWxkIGJlIGdvb2QgZm9yIERFLgoKSGVyZSB3ZSBnZW5lcmF0ZSBzY2F0dGVyIHBsb3RzIGNvbXBhcmluZyBkaXNwZXJzaW9uIGVzdGltYXRlcyB3aXRoaW4gZWFjaCBiYXRjaCB0byBlc3RpbWF0ZXMgZnJvbSB3aG9sZSBkYXRhc2V0ICgqKmluY2x1ZGluZyBiYXRjaCBhcyBhIGNvdmFyaWF0ZSBpbiB3aG9sZSBzdHVkeSoqKS4KCmBgYHtyLCBlY2hvPUZBTFNFLCByZXN1bHRzPSdoaWRlJ30KIyMgIERpc3BlcnNpb24gaW4gYmF0Y2hlcyAmIGluIHdob2xlIHN0dWR5IChpbmNsdWRpbmcgYmF0Y2ggYXMgY292YXJpYXRlKSAoZWRnZVIpCnlfYmF0Y2gxIDwtIERHRUxpc3QoY291bnRzPWN0c1ssIGJhdGNoPT0xXSwgZ3JvdXA9YXMuZmFjdG9yKGdyb3VwX251bVtiYXRjaD09MV0pKQp5X2JhdGNoMSA8LSBjYWxjTm9ybUZhY3RvcnMoeV9iYXRjaDEsIG1ldGhvZD0iVE1NIikKZGVzaWduX2JhdGNoMSA8LSBtb2RlbC5tYXRyaXgofmFzLmZhY3Rvcihncm91cF9udW1bYmF0Y2g9PTFdKSkKeV9iYXRjaDEgPC0gZXN0aW1hdGVEaXNwKHlfYmF0Y2gxLCBkZXNpZ25fYmF0Y2gxKQoKeV9iYXRjaDIgPC0gREdFTGlzdChjb3VudHM9Y3RzWywgYmF0Y2g9PTJdLCBncm91cD1hcy5mYWN0b3IoZ3JvdXBfbnVtW2JhdGNoPT0yXSkpCnlfYmF0Y2gyIDwtIGNhbGNOb3JtRmFjdG9ycyh5X2JhdGNoMiwgbWV0aG9kPSJUTU0iKQpkZXNpZ25fYmF0Y2gyIDwtIG1vZGVsLm1hdHJpeCh+YXMuZmFjdG9yKGdyb3VwX251bVtiYXRjaD09Ml0pKQp5X2JhdGNoMiA8LSBlc3RpbWF0ZURpc3AoeV9iYXRjaDIsIGRlc2lnbl9iYXRjaDIpCgp5X2JhdGNoMyA8LSBER0VMaXN0KGNvdW50cz1jdHNbLCBiYXRjaD09M10sIGdyb3VwPWFzLmZhY3Rvcihncm91cF9udW1bYmF0Y2g9PTNdKSkKeV9iYXRjaDMgPC0gY2FsY05vcm1GYWN0b3JzKHlfYmF0Y2gzLCBtZXRob2Q9IlRNTSIpCmRlc2lnbl9iYXRjaDMgPC0gbW9kZWwubWF0cml4KH5hcy5mYWN0b3IoZ3JvdXBfbnVtW2JhdGNoPT0zXSkpCnlfYmF0Y2gzIDwtIGVzdGltYXRlRGlzcCh5X2JhdGNoMywgZGVzaWduX2JhdGNoMykKCnlfd2hvbGUgPC0gREdFTGlzdChjb3VudHM9Y3RzKQp5X3dob2xlIDwtIGNhbGNOb3JtRmFjdG9ycyh5X3dob2xlLCBtZXRob2Q9IlRNTSIpCmRlc2lnbl93aG9sZSA8LSBtb2RlbC5tYXRyaXgofiBhcy5mYWN0b3IoZ3JvdXBfbnVtKSArIGFzLmZhY3RvcihiYXRjaCkpCnlfd2hvbGUgPC0gZXN0aW1hdGVEaXNwKHlfd2hvbGUsIGRlc2lnbl93aG9sZSkKCmRpc3AxX2dlbmVfZWRnZVIgPC0geV9iYXRjaDEkdGFnd2lzZS5kaXNwZXJzaW9uCmRpc3AyX2dlbmVfZWRnZVIgPC0geV9iYXRjaDIkdGFnd2lzZS5kaXNwZXJzaW9uCmRpc3AzX2dlbmVfZWRnZVIgPC0geV9iYXRjaDMkdGFnd2lzZS5kaXNwZXJzaW9uCmRpc3BXX2dlbmVfZWRnZVIgPC0geV93aG9sZSR0YWd3aXNlLmRpc3BlcnNpb24KCmRpc3AxX3RyZW5kX2VkZ2VSIDwtIHlfYmF0Y2gxJHRyZW5kZWQuZGlzcGVyc2lvbgpkaXNwMl90cmVuZF9lZGdlUiA8LSB5X2JhdGNoMiR0cmVuZGVkLmRpc3BlcnNpb24KZGlzcDNfdHJlbmRfZWRnZVIgPC0geV9iYXRjaDMkdHJlbmRlZC5kaXNwZXJzaW9uCmRpc3BXX3RyZW5kX2VkZ2VSIDwtIHlfd2hvbGUkdHJlbmRlZC5kaXNwZXJzaW9uCgoKIyMgIERpc3BlcnNpb24gaW4gYmF0Y2hlcyAmIGluIHdob2xlIHN0dWR5IChpbmNsdWRpbmcgYmF0Y2ggYXMgY292YXJpYXRlKSAoREVTZXEyKQpkZHMxIDwtIERFU2VxRGF0YVNldEZyb21NYXRyaXgoY291bnREYXRhPWN0c1ssYmF0Y2g9PTFdLCBkZXNpZ249fkdyb3VwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sRGF0YT1kYXRhLmZyYW1lKEdyb3VwPWFzLmZhY3Rvcihncm91cF9udW1bYmF0Y2g9PTFdKSkpCmRkczEgPC0gZXN0aW1hdGVTaXplRmFjdG9ycyhkZHMxKQpkZHMxIDwtIGVzdGltYXRlRGlzcGVyc2lvbnMoZGRzMSkKCmRkczIgPC0gREVTZXFEYXRhU2V0RnJvbU1hdHJpeChjb3VudERhdGE9Y3RzWyxiYXRjaD09Ml0sIGRlc2lnbj1+R3JvdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xEYXRhPWRhdGEuZnJhbWUoR3JvdXA9YXMuZmFjdG9yKGdyb3VwX251bVtiYXRjaD09Ml0pKSkKZGRzMiA8LSBlc3RpbWF0ZVNpemVGYWN0b3JzKGRkczIpCmRkczIgPC0gZXN0aW1hdGVEaXNwZXJzaW9ucyhkZHMyKQoKZGRzMyA8LSBERVNlcURhdGFTZXRGcm9tTWF0cml4KGNvdW50RGF0YT1jdHNbLGJhdGNoPT0zXSwgZGVzaWduPX5Hcm91cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbERhdGE9ZGF0YS5mcmFtZShHcm91cD1hcy5mYWN0b3IoZ3JvdXBfbnVtW2JhdGNoPT0zXSkpKQpkZHMzIDwtIGVzdGltYXRlU2l6ZUZhY3RvcnMoZGRzMykKZGRzMyA8LSBlc3RpbWF0ZURpc3BlcnNpb25zKGRkczMpCgpkZHNXIDwtIERFU2VxRGF0YVNldEZyb21NYXRyaXgoY291bnREYXRhPWN0cywgZGVzaWduPX5Hcm91cCArIEJhdGNoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sRGF0YT1kYXRhLmZyYW1lKEdyb3VwPWFzLmZhY3Rvcihncm91cF9udW0pLCBCYXRjaD1hcy5mYWN0b3IoYmF0Y2gpKSkKZGRzVyA8LSBlc3RpbWF0ZVNpemVGYWN0b3JzKGRkc1cpCmRkc1cgPC0gZXN0aW1hdGVEaXNwZXJzaW9ucyhkZHNXKQoKZGlzcDFfZ2VuZV9ERVNlcTIgPC0gZGlzcGVyc2lvbnMoZGRzMSkKZGlzcDJfZ2VuZV9ERVNlcTIgPC0gZGlzcGVyc2lvbnMoZGRzMikKZGlzcDNfZ2VuZV9ERVNlcTIgPC0gZGlzcGVyc2lvbnMoZGRzMykKZGlzcFdfZ2VuZV9ERVNlcTIgPC0gZGlzcGVyc2lvbnMoZGRzVykKYGBgCgoKIyMjIEdlbmUtd2lzZSBkaXNwZXJzaW9uIGVzdGltYXRlcwoKYGBge3IsIGVjaG89RkFMU0UsIHJlc3VsdHM9J2hpZGUnLCBmaWcud2lkdGg9NCwgZmlnLmhlaWdodD0xMn0KZGlzcHNfYWxsIDwtIGRhdGEuZnJhbWUoQmF0Y2gxLmVkZ2VSPWRpc3AxX2dlbmVfZWRnZVIsIAogICAgICAgICAgICAgICAgICAgICAgICBCYXRjaDIuZWRnZVI9ZGlzcDJfZ2VuZV9lZGdlUiwgCiAgICAgICAgICAgICAgICAgICAgICAgIEJhdGNoMy5lZGdlUj1kaXNwM19nZW5lX2VkZ2VSLAogICAgICAgICAgICAgICAgICAgICAgICBXaG9sZS5lZGdlUj1kaXNwV19nZW5lX2VkZ2VSLAogICAgICAgICAgICAgICAgICAgICAgICBCYXRjaDEuZWRnZVIudHJlbmQ9ZGlzcDFfdHJlbmRfZWRnZVIsIAogICAgICAgICAgICAgICAgICAgICAgICBCYXRjaDIuZWRnZVIudHJlbmQ9ZGlzcDJfdHJlbmRfZWRnZVIsIAogICAgICAgICAgICAgICAgICAgICAgICBCYXRjaDMuZWRnZVIudHJlbmQ9ZGlzcDNfdHJlbmRfZWRnZVIsIAogICAgICAgICAgICAgICAgICAgICAgICBXaG9sZS5lZGdlUi50cmVuZD1kaXNwV190cmVuZF9lZGdlUiwKICAgICAgICAgICAgICAgICAgICAgICAgQmF0Y2gxLkRFU2VxMj1kaXNwMV9nZW5lX0RFU2VxMiwgCiAgICAgICAgICAgICAgICAgICAgICAgIEJhdGNoMi5ERVNlcTI9ZGlzcDJfZ2VuZV9ERVNlcTIsIAogICAgICAgICAgICAgICAgICAgICAgICBCYXRjaDMuREVTZXEyPWRpc3AzX2dlbmVfREVTZXEyLCAKICAgICAgICAgICAgICAgICAgICAgICAgV2hvbGUuREVTZXEyPWRpc3BXX2dlbmVfREVTZXEyKQpkaXNwc19hbGxfbG9nMTAgPC0gbG9nMTAoZGlzcHNfYWxsKQoKcGx0X3JhbmdlX2VkZ2VSIDwtIHJhbmdlKGMoZGlzcDFfZ2VuZV9lZGdlUiwgZGlzcDJfZ2VuZV9lZGdlUiwgZGlzcDNfZ2VuZV9lZGdlUiwgZGlzcFdfZ2VuZV9lZGdlUiksIG5hLnJtPVRSVUUpCnBsdF9yYW5nZV9lZGdlUnRyZW5kIDwtIHJhbmdlKGMoZGlzcDFfdHJlbmRfZWRnZVIsIGRpc3AyX3RyZW5kX2VkZ2VSLCBkaXNwM190cmVuZF9lZGdlUiwgZGlzcFdfdHJlbmRfZWRnZVIpLCBuYS5ybT1UUlVFKQpwbHRfcmFuZ2VfREVTZXEyIDwtIHJhbmdlKGMoZGlzcDFfZ2VuZV9ERVNlcTIsIGRpc3AyX2dlbmVfREVTZXEyLCBkaXNwM19nZW5lX0RFU2VxMiwgZGlzcFdfZ2VuZV9ERVNlcTIpLCBuYS5ybT1UUlVFKQoKcGx0X3JhbmdlX2VkZ2VSX2xvZzEwIDwtIGxvZzEwKHBsdF9yYW5nZV9lZGdlUikKcGx0X3JhbmdlX2VkZ2VSdHJlbmRfbG9nMTAgPC0gbG9nMTAocGx0X3JhbmdlX2VkZ2VSdHJlbmQpCnBsdF9yYW5nZV9ERVNlcTJfbG9nMTAgPC0gbG9nMTAocGx0X3JhbmdlX0RFU2VxMikKCmdlblNjYXR0ZXJQbG90IDwtIGZ1bmN0aW9uKGRmLCBhZXMueCwgYWVzLnksIG1ldGhvZCwgcGx0LnJhbmdlKXsKICBwIDwtIGdncGxvdChkZiwgYWVzKHg9ZGZbLGFlcy54XSwgeT1kZlssYWVzLnldKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9hYmxpbmUoc2xvcGU9MSwgaW50ZXJjZXB0PTAsIGNvbG9yPSJibHVlIiwgbGluZXR5cGU9ImRhc2hlZCIpICsKICBsYWJzKHRpdGxlPXNwcmludGYoIiVzLCBQZWFyc29uIGNvcnIgPSAlcyIsIG1ldGhvZCwKICAgICAgICAgICAgICAgICAgICAgcm91bmQoY29yKGRmWyxhZXMueF0sIGRmWyxhZXMueV0sIHVzZT0icGFpcndpc2UuY29tcGxldGUub2JzIiwgbWV0aG9kPSJwZWFyc29uIiksMikpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cz1wbHQucmFuZ2UpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzPXBsdC5yYW5nZSkKfQoKcDFXX2VkZ2VSIDwtIGdlblNjYXR0ZXJQbG90KGRpc3BzX2FsbF9sb2cxMCwgYWVzLng9Ildob2xlLmVkZ2VSIiwgYWVzLnk9IkJhdGNoMS5lZGdlUiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kPSJlZGdlUiIsIHBsdC5yYW5nZT1wbHRfcmFuZ2VfZWRnZVJfbG9nMTApICsgCiAgbGFicyh4PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSB3aG9sZSBkYXRhc2V0IiwgeT0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gYmF0Y2ggMSIpCnAyV19lZGdlUiA8LSBnZW5TY2F0dGVyUGxvdChkaXNwc19hbGxfbG9nMTAsIGFlcy54PSJXaG9sZS5lZGdlUiIsIGFlcy55PSJCYXRjaDIuZWRnZVIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZD0iZWRnZVIiLCBwbHQucmFuZ2U9cGx0X3JhbmdlX2VkZ2VSX2xvZzEwKSArCiAgbGFicyh4PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSB3aG9sZSBkYXRhc2V0IiwgeT0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gYmF0Y2ggMiIpCnAzV19lZGdlUiA8LSBnZW5TY2F0dGVyUGxvdChkaXNwc19hbGxfbG9nMTAsIGFlcy54PSJXaG9sZS5lZGdlUiIsIGFlcy55PSJCYXRjaDMuZWRnZVIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZD0iZWRnZVIiLCBwbHQucmFuZ2U9cGx0X3JhbmdlX2VkZ2VSX2xvZzEwKSArCiAgbGFicyh4PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSB3aG9sZSBkYXRhc2V0IiwgeT0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gYmF0Y2ggMyIpCnAxdjJfZWRnZVIgPC0gZ2VuU2NhdHRlclBsb3QoZGlzcHNfYWxsX2xvZzEwLCBhZXMueD0iQmF0Y2gxLmVkZ2VSIiwgYWVzLnk9IkJhdGNoMi5lZGdlUiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZD0iZWRnZVIiLCBwbHQucmFuZ2U9cGx0X3JhbmdlX2VkZ2VSX2xvZzEwKSArCiAgbGFicyh4PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBiYXRjaCAxIiwgeT0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gYmF0Y2ggMiIpCnAxdjNfZWRnZVIgPC0gZ2VuU2NhdHRlclBsb3QoZGlzcHNfYWxsX2xvZzEwLCBhZXMueD0iQmF0Y2gxLmVkZ2VSIiwgYWVzLnk9IkJhdGNoMy5lZGdlUiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZD0iZWRnZVIiLCBwbHQucmFuZ2U9cGx0X3JhbmdlX2VkZ2VSX2xvZzEwKSArCiAgbGFicyh4PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBiYXRjaCAxIiwgeT0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gYmF0Y2ggMyIpCnAydjNfZWRnZVIgPC0gZ2VuU2NhdHRlclBsb3QoZGlzcHNfYWxsX2xvZzEwLCBhZXMueD0iQmF0Y2gyLmVkZ2VSIiwgYWVzLnk9IkJhdGNoMy5lZGdlUiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZD0iZWRnZVIiLCBwbHQucmFuZ2U9cGx0X3JhbmdlX2VkZ2VSX2xvZzEwKSArCiAgbGFicyh4PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBiYXRjaCAyIiwgeT0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gYmF0Y2ggMyIpICAgIAogIApwMVdfREVTZXEyIDwtIGdlblNjYXR0ZXJQbG90KGRpc3BzX2FsbF9sb2cxMCwgYWVzLng9Ildob2xlLkRFU2VxMiIsIGFlcy55PSJCYXRjaDEuREVTZXEyIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kPSJERVNlcTIiLCBwbHQucmFuZ2U9cGx0X3JhbmdlX0RFU2VxMl9sb2cxMCkgKyAKICBsYWJzKHg9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIHdob2xlIGRhdGFzZXQiLCB5PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBiYXRjaCAxIikKcDJXX0RFU2VxMiA8LSBnZW5TY2F0dGVyUGxvdChkaXNwc19hbGxfbG9nMTAsIGFlcy54PSJXaG9sZS5ERVNlcTIiLCBhZXMueT0iQmF0Y2gyLkRFU2VxMiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZD0iREVTZXEyIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9ERVNlcTJfbG9nMTApICsKICBsYWJzKHg9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIHdob2xlIGRhdGFzZXQiLCB5PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBiYXRjaCAyIikKcDNXX0RFU2VxMiA8LSBnZW5TY2F0dGVyUGxvdChkaXNwc19hbGxfbG9nMTAsIGFlcy54PSJXaG9sZS5ERVNlcTIiLCBhZXMueT0iQmF0Y2gzLkRFU2VxMiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZD0iREVTZXEyIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9ERVNlcTJfbG9nMTApICsKICBsYWJzKHg9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIHdob2xlIGRhdGFzZXQiLCB5PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBiYXRjaCAzIikKcDF2Ml9ERVNlcTIgPC0gZ2VuU2NhdHRlclBsb3QoZGlzcHNfYWxsX2xvZzEwLCBhZXMueD0iQmF0Y2gxLkRFU2VxMiIsIGFlcy55PSJCYXRjaDIuREVTZXEyIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZD0iREVTZXEyIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9ERVNlcTJfbG9nMTApICsKICBsYWJzKHg9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIGJhdGNoIDEiLCB5PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBiYXRjaCAyIikKcDF2M19ERVNlcTIgPC0gZ2VuU2NhdHRlclBsb3QoZGlzcHNfYWxsX2xvZzEwLCBhZXMueD0iQmF0Y2gxLkRFU2VxMiIsIGFlcy55PSJCYXRjaDMuREVTZXEyIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZD0iREVTZXEyIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9ERVNlcTJfbG9nMTApICsKICBsYWJzKHg9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIGJhdGNoIDEiLCB5PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBiYXRjaCAzIikKcDJ2M19ERVNlcTIgPC0gZ2VuU2NhdHRlclBsb3QoZGlzcHNfYWxsX2xvZzEwLCBhZXMueD0iQmF0Y2gyLkRFU2VxMiIsIGFlcy55PSJCYXRjaDMuREVTZXEyIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZD0iREVTZXEyIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9ERVNlcTJfbG9nMTApICsKICBsYWJzKHg9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIGJhdGNoIDIiLCB5PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBiYXRjaCAzIikgICAgCgpncmlkLmFycmFuZ2UocDFXX2VkZ2VSLCBwMVdfREVTZXEyLCBwMldfZWRnZVIsIHAyV19ERVNlcTIsIHAzV19lZGdlUiwgcDNXX0RFU2VxMiwKICAgICAgICAgICAgIHAxdjJfZWRnZVIsIHAxdjJfREVTZXEyLCBwMXYzX2VkZ2VSLCBwMXYzX0RFU2VxMiwgcDJ2M19lZGdlUiwgcDJ2M19ERVNlcTIsCiAgICAgICAgICAgICBucm93PTYsIG5jb2w9MikKYGBgCgojIyMgVHJlbmRlZCBkaXNwZXJzaW9uIGVzdGltYXRlcyAobG9nMTAgc2NhbGUpCgpgYGB7ciwgZWNobz1GQUxTRSwgcmVzdWx0cz0naGlkZScsIGZpZy53aWR0aD00LCBmaWcuaGVpZ2h0PTEyfQpwMVdfZWRnZVIgPC0gZ2VuU2NhdHRlclBsb3QoZGlzcHNfYWxsX2xvZzEwLCBhZXMueD0iV2hvbGUuZWRnZVIudHJlbmQiLCBhZXMueT0iQmF0Y2gxLmVkZ2VSLnRyZW5kIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2Q9ImVkZ2VSIHRyZW5kIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9lZGdlUnRyZW5kX2xvZzEwKSArIAogIGxhYnMoeD0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gd2hvbGUgZGF0YXNldCIsIHk9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIGJhdGNoIDEiKQpwMldfZWRnZVIgPC0gZ2VuU2NhdHRlclBsb3QoZGlzcHNfYWxsX2xvZzEwLCBhZXMueD0iV2hvbGUuZWRnZVIudHJlbmQiLCBhZXMueT0iQmF0Y2gyLmVkZ2VSLnRyZW5kIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2Q9ImVkZ2VSIHRyZW5kIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9lZGdlUnRyZW5kX2xvZzEwKSArCiAgbGFicyh4PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSB3aG9sZSBkYXRhc2V0IiwgeT0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gYmF0Y2ggMiIpCnAzV19lZGdlUiA8LSBnZW5TY2F0dGVyUGxvdChkaXNwc19hbGxfbG9nMTAsIGFlcy54PSJXaG9sZS5lZGdlUi50cmVuZCIsIGFlcy55PSJCYXRjaDMuZWRnZVIudHJlbmQiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZD0iZWRnZVIgdHJlbmQiLCBwbHQucmFuZ2U9cGx0X3JhbmdlX2VkZ2VSdHJlbmRfbG9nMTApICsKICBsYWJzKHg9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIHdob2xlIGRhdGFzZXQiLCB5PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBiYXRjaCAzIikKcDF2Ml9lZGdlUiA8LSBnZW5TY2F0dGVyUGxvdChkaXNwc19hbGxfbG9nMTAsIGFlcy54PSJCYXRjaDEuZWRnZVIudHJlbmQiLCBhZXMueT0iQmF0Y2gyLmVkZ2VSLnRyZW5kIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kPSJlZGdlUiB0cmVuZCIsIHBsdC5yYW5nZT1wbHRfcmFuZ2VfZWRnZVJ0cmVuZF9sb2cxMCkgKwogIGxhYnMoeD0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gYmF0Y2ggMSIsIHk9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIGJhdGNoIDIiKQpwMXYzX2VkZ2VSIDwtIGdlblNjYXR0ZXJQbG90KGRpc3BzX2FsbF9sb2cxMCwgYWVzLng9IkJhdGNoMS5lZGdlUi50cmVuZCIsIGFlcy55PSJCYXRjaDMuZWRnZVIudHJlbmQiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2Q9ImVkZ2VSIHRyZW5kIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9lZGdlUnRyZW5kX2xvZzEwKSArCiAgbGFicyh4PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBiYXRjaCAxIiwgeT0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gYmF0Y2ggMyIpCnAydjNfZWRnZVIgPC0gZ2VuU2NhdHRlclBsb3QoZGlzcHNfYWxsX2xvZzEwLCBhZXMueD0iQmF0Y2gyLmVkZ2VSLnRyZW5kIiwgYWVzLnk9IkJhdGNoMy5lZGdlUi50cmVuZCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZD0iZWRnZVIgdHJlbmQiLCBwbHQucmFuZ2U9cGx0X3JhbmdlX2VkZ2VSdHJlbmRfbG9nMTApICsKICBsYWJzKHg9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIGJhdGNoIDIiLCB5PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBiYXRjaCAzIikgICAgCiAgCmdyaWQuYXJyYW5nZShwMVdfZWRnZVIsIHAxV19ERVNlcTIsIHAyV19lZGdlUiwgcDJXX0RFU2VxMiwgcDNXX2VkZ2VSLCBwM1dfREVTZXEyLAogICAgICAgICAgICAgcDF2Ml9lZGdlUiwgcDF2Ml9ERVNlcTIsIHAxdjNfZWRnZVIsIHAxdjNfREVTZXEyLCBwMnYzX2VkZ2VSLCBwMnYzX0RFU2VxMiwKICAgICAgICAgICAgIG5yb3c9NiwgbmNvbD0yKQpgYGAKCgoKIyMgU2Vzc2lvbiBpbmZvIAoKYGBge3IsIGVjaG89RkFMU0V9CnNlc3Npb25JbmZvKCkKYGBgCgoKCiMjIFJlZmVyZW5jZXMK